先對陣列排序,然後取中位數,那個中位數肯定是超過一半的數字。採用快速排序時間複雜度為o(nlogn)+取中位數o(n)。
基於partition函式的時間複雜度為o(n)的演算法。
這種演算法受快速排序演算法的啟發。在隨機快速排序演算法中,現在陣列中隨機選擇乙個 數字,然後調整陣列中數字的順序,使得比選中的數字小的數字
都排在它的左邊,比選中的數字大的數字都排在它的右邊。如果這個選中的數字的下標剛好是n/2,那麼這個數字就是陣列的中位數;如果它的下標大於
n/2,那麼中位數應該位於它的左邊,可以接著在它的左邊部分的陣列中查詢;如果它的下標小於n/2,那麼中位數應該位於它的右邊,可以接著在它的
右邊陣列中查詢。這是乙個典型的遞迴過程,**實現:
int morethanhalfnum_solution1(int* numbers, int length)
else
}int result = numbers[middle];
if(!checkmorethanhalf(numbers, length, result))
result = 0;
return result;
}
我們可以考慮在遍歷陣列的時候儲存兩個值:乙個是數值中的乙個數字;另乙個是次數。當我們遍歷到下乙個數字的時候,如果下乙個數字和我們
之前儲存的數字相同,則次數加1;如果下乙個數字和我們儲存的數字不同,則次數減1.如果次數為零,那我們需要儲存下乙個數字,並把次數設為1. 由於我們
要找的數字出現的次數比其他所有數字出現的次數和還要多,那麼要找的數字肯定是最後一次把次數設為1時對應的數字。
int morethanhalfnum_solution2(int* numbers, int length)
else if(numbers[i] == result)
times++;
else
times--;
}if(!checkmorethanhalf(numbers, length, result))
result = 0;
return result;
}
方法四:使用hashmap()
用到了hashmap來記錄每個出現的數字以及出現的次數。在一些筆試面試中,總會出現 類似問題,但都會告訴你陣列超大,
小用了。遍歷陣列,利用hashmap記錄每個數字以及數字出現的次數。時間複雜度為o(n)
方法五:刪除兩個不同的值
如果乙個數字出現的次數超過陣列長度的一半,所以這個數字出現的次數比其他數出現的次數的總和還多。考慮每次刪除兩個
不同的數,那麼在剩下的數中,出現的次數仍然超過總數的一般,不斷重複該過程,排除掉其他的數,最終剩下的數字就是要
找的(如果存在)。這個方法的時間複雜度是o(n),空間複雜度是o(1)。
劍指offer 39 陣列中出現超過一半的數
這道題的題目為 陣列中有乙個數字出現的次數超過陣列長度的一半,請找出這個數字。解題思路分為三步 1 對陣列進行排序,排序之後位於中間的那個數字就是出現的次數超過陣列長度的一半的數。2 使用partition演算法對陣列進行排序,使得排序後隨機選取的數字的左邊數都小於它,右邊都大於它。如果選中的數字下...
劍指offer第39 陣列中出現次數超過一半的數字
陣列中有乙個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入乙個長度為9的陣列。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。coding utf 8 classsolution defmorethanhalfnum solution self numb...
劍指offer(39)陣列中重複的數字
在乙個長度為n的陣列裡的所有數字都在0到n 1的範圍內。陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意乙個重複的數字。例如,如果輸入長度為7的陣列,那麼對應的輸出是第乙個重複的數字2。設定乙個比較陣列 返回值即可 重複了就break public bo...