算法數據結構面試分享(六)數組排序問題(2) - 計數排序

數組排序問題(2)

    昨天我們留了一道題目“給你一個整型數組,裏面出現的數在[0-100] 之間,能用最優化的方法幫我排序嗎”。

一、確保我們理解了問題,並且嘗試一個例子,確認理解無誤。 
    這是一道排序算法題,我們學過很多排序的算法。不一樣的是,它給定一個額外的條件,數組裏的每個數字都在1-100之間。如果我們採取傳統的排序算法,這個條件我們好像用不上。大家在面試的時候如果發現有條件沒有用上,基本上我們給出的算法可能不是最優的,或者我們沒有解決它最原始的需求。舉個例子{50, 46, 50, 0, 100,0} 這個數組中,我們一眼就能看出來 0 有兩個, 46有一個,50有兩個,100有一個,我們再把他們拼接起來,我們就會得到 {0,0, 46, 50, 50,100}。

二、想想你可以用什麼方法解決問題,你會選擇哪一種,爲什麼?
  在上面的分析中我們能夠總結出來,我們人工去排序的時候涉及到了兩個重要的步驟。1:統計0 - 100 之間每一個數出現的次數: 2: 從0 - 100 的順序按照他們出現的次數拼接出來。所以現在我們需要解決的問題如何方便計數了。申明一個數字,長度爲101,假設50出現了一次,我們就把該數組中下標爲50的位置加上1. 全部計數完了,我們再掃描這個數字,將結果寫回。
    我們現在看一下它的複雜度,我們掃描了原數組一次,又掃描了計數數組一次,所以我們的複雜度是O(n). 這裏大家也發現,我們這道題中體現了一個原則,用空間換時間。

三、 解釋你的算法和實現的方法
    1. 計數部分:掃描原數組, 在index數組中找到對應的位置

int[] indexArray = new int[100];

foreach(var e in inputArray)

{

  indexArray[e] ++;

}

    2. 合併數組部分

int count = 0;

for(int index = 0; index < indexArray.Length; index++)

{

if(indexArray[index] > 0 ) //說明index的數字出現過,我們需要拼接起來,出現了幾次我們就加幾個數

 {

 inputArray[count] = index;

 count ++; 

}

}


四、寫代碼的時候,記住,一定要解釋你現在在幹什麼 
       那我們就直接上代碼啦。

 /// <summary>
        /// 給數組排序,該數組裏的值在0-100之間
        /// </summary>
        /// <param name="array"></param>
        public static void IndexSort(int[] array)
        {
            int[] indexArray = new int[101];

            for (var index = 0; index < indexArray.Length; index++)
            {
                indexArray[index] = 0;
            }

            foreach (var e in array)
            {
                indexArray[e]++;
            }

            int count = 0;
            for (int index = 0; index < indexArray.Length; index++)
            {
                if (indexArray[index] > 0)
                {
                    for (int elementCount = 0; elementCount < indexArray[index]; elementCount++)
                    {
                        array[count++] = index;
                    }
                }
            }     
        }

大家有沒有發現,上面的代碼其實可以優化,會體現你的基本功哦。要裝逼的話可以和面試官提出來的哦。int的默認值是0,所以我們沒有必要掃描它一遍給它賦個默認值了。所以這段代碼是多餘的:

            for (var index = 0; index < indexArray.Length; index++)
            {
               indexArray[index] = 0;
            }

我們來測試一下這個方法:

      static void Main(string[] args)
        {
            int[] array = new int[] { 100, 8, 0, 7, 0, 34 };

            IndexSort(array);

            foreach(var e in array)
            {
                Console.Write(e + " " );
            }
        }

五、 Workthrough
六、 修復缺陷

我們得到的結果:


大功告成了哈。 如果大家對以上的算法有什麼疑問,或者更好的解法,歡迎交流。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章