我的個人微信公衆號:Microstrong
微信公衆號ID:MicrostrongAI
微信公衆號介紹:Microstrong(小強)同學主要研究機器學習、深度學習、計算機視覺、智能對話系統相關內容,分享在學習過程中的讀書筆記!期待您的關注,歡迎一起學習交流進步!
知乎主頁:https://www.zhihu.com/people/MicrostrongAI/activities
題目鏈接:
題目描述:
解題思路:
(1)數組中的數兩兩相加,找出乘積最小的解
時間複雜度爲
已經AC的代碼:
# -*- coding:utf-8 -*-
class Solution:
def FindNumbersWithSum(self, array, tsum):
result_list = []
for index, value in enumerate(array):
for j in range(index, len(array)):
if value + array[j] == tsum:
result_list.append(value)
result_list.append(array[j])
break
if len(result_list) == 2:
break
return result_list
def FindNumbersWithSum2(self, array, tsum):
if __name__ == "__main__":
sol = Solution()
array = [1, 3, 5, 15, 17]
tsum = 20
print(sol.FindNumbersWithSum(array, tsum))
(2)設置兩個指針,時間複雜度
例如,輸入數組{1, 2, 4, 7, 11 , 15}和數字15。由於4 + 11 = 15, 因此輸出4和11。
在面試的時候,很重要的一點是應聘者要表現出很快的反應能力。只要想到一種方法,應聘者就可以馬上告訴面試官,即使這種方法不一定是最好的。比如這個問題,很多人都能立即想到的方法,也就是先在數組中固定一個數字,再依次判斷數組中其餘的 n-1 個數字與它的和是不是等於s。面試官會告訴我們這不是最好的辦法。不過這沒有關係,至少面試官知道我們的思維還是比較敏捷的。
接着我們尋找更好的算法。我們先在數組中選擇兩個數字,如果它們的和等於輸入的s,那麼我們就找到了要找的兩個數字。如果和小於s呢?我們希望兩個數字的和再大一點。由於數組已經排好序了,我們可以考慮選擇較小的數字後面的數字。因爲排在後面的數字要大一些,那麼兩個數字的和也要大一些,就有可能等於輸入的數字s了。同樣,當兩個數字的和大於輸入的數字的時候,我們可以選擇較大數字前面的數字,因爲排在數組前面的數字要小一些。
我們以數組{1, 2, 4, 7, 11, 15}及期待的和15爲例詳細分析一下這個過程。首先定義兩個指針,第一個指針指向數組的第一個(最小的)數字1,第二個指針指向數組的最後一個(最大的)數字15。這兩個數字的和16大於15, 因此我們把第二個指針向前移動一個數字,讓它指向11。這時候兩個數字1與11的和是12,小於15。接下來我們把第一個指針向後移動一個數字指向2,此時兩個數字2與11的和是13,還是小於15。我們再次向後移動第一個指針, 讓它指向數字4。 數字4與11的和是15,正是我們期待的結果。 下表總結了在數組{1, 2, 4, 7,11,15}中查找和爲15的數對的過程。
步驟 | 較小的數字 | 較大的數字 | 和 | 與s相比較 | 下一步操作 |
1 | 1 | 15 | 16 | 大於 | 選擇15之前的數字 |
2 | 1 | 11 | 12 | 小於 | 選擇1之後的數字 |
3 | 2 | 11 | 13 | 小於 | 選擇2之後的數字 |
4 | 4 | 11 | 15 | 等於 |
這一次面試官會首肯我們的思路,於是就可以動手寫代碼了。 下面是已經AC的代碼:
# -*- coding:utf-8 -*-
class Solution:
def FindNumbersWithSum(self, array, tsum):
# write code here
if array is None or len(array) < 1:
return []
start = 0
end = len(array) - 1
result_list = []
while start <= end:
if array[start] + array[end] > tsum:
end -= 1
elif array[start] + array[end] < tsum:
start += 1
elif len(result_list) == 2:
break
elif array[start] + array[end] == tsum:
result_list.append(array[start])
result_list.append(array[end])
return result_list
在上述代碼中, start爲較小的數字的下標, end爲較大的數字的下標。由於數組是排序的,因此較小數字一定位於較大數字的前面, 這就是while循環繼續的條件是 start <= end 的原因。 代碼中只有一個while循環從兩端向中間掃描數組,因此這種算法的時間複雜度是。
Reference:
【1】《劍指offer》,何海濤著。
【2】https://blog.nowcoder.net/n/0935efd26ade435497dcbe407cfc94ec