第2章 面試需要的基礎知識
第3章 高質量的代碼
第4章 解決面試題的思路
面試題27:二叉樹的鏡像
面試題29:順時針打印矩陣
面試題30 :包含min函數的棧
面試題31:棧的壓入、彈出序列
面試題32:上往下打印二叉樹
面試題33: 二叉搜索樹的後序遍歷序列
面試題34: 二叉樹中和爲某一值的路徑
面試題35:複雜鏈表的複製
面試題36:二叉搜索樹與雙向鏈表
面試題38:字符串的排列
第5章 優化時間和空間效率
第6章 面試中的各項能力
第7章 兩個面試案例
題目描述
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲9的數組{1,2,3,2,2,2,5,4,2}。由於數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。
解題思路
牛客網
方法一:
數組中有一個數字出現的次數超過數組長度的一半,所以它出現的次數比其它數出現的次數總和還多。考慮在遍歷數組時保存兩個值:一個是數組中的一個數字,另一個是次數。
當我們遍歷到下一個數字時,如果下一個數字和我們之前保存的數字相同,則次數加1;如果不同,則次數減1。如果次數爲零,則需要保存下一個數字,並把次數設爲1。這樣要找的數字可能是最後一次把次數設爲1時對應的數字,還需要統計這個數字在數組中的數量才能確認。
實戰
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
length = len(numbers)
i = 0
counts = 0
while i < length:
if counts == 0:
digit = numbers[i]
i += 1
counts = 1
continue
if numbers[i] != digit:
counts -= 1
else:
counts += 1
i += 1
counts = 0
for num in numbers:
if num == digit:
counts += 1
if counts > length >> 1:
return digit
return 0
方法二:
受快速排序啓發,有成熟的得到數組中任意第k大數字的算法,且時間複雜度爲O(n)。如果數組有一個數其數量超過數組長度一半,那麼排序後的數組其中間位置的數一定就是那個次數超過一半的數,所以這道題可以引申爲尋找排序數組的中間位置數。
我們先隨機選取一個數字,然後調整數組順序,使得比選中數字大的數在其右邊,小的數在其左邊。如果選中的數其索引恰好爲n/2,則這個數就是中間位置數;如果其索引大於n/2,那麼中間位置數在這個數的左邊,然後繼續去左邊數組中查找;否則中間位置數在其右邊,繼續去右邊數組中查找。這是一個典型的遞歸過程。
實戰
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
# write code here
if not numbers:
return numbers
def recc(begin, end):
if begin >= end:
return numbers[begin]
index = begin
for i in range(begin+1, end+1):
if numbers[index] > numbers[i]:
numbers[index], numbers[i] = numbers[i], numbers[index]
index = i
if index == length >> 1:
return numbers[index]
if index > length >> 1:
num = recc(begin, index-1)
else:
num = recc(index+1, end)
return num
length = len(numbers)
number = recc(0, length-1)
counts = 0
for i in range(length):
if number == numbers[i]:
counts += 1
if counts > length >> 1:
return number
return 0