牛客網在線編程專題《劍指offer-面試題41》和爲S的兩個數字

我的個人微信公衆號:Microstrong

微信公衆號ID:MicrostrongAI

微信公衆號介紹:Microstrong(小強)同學主要研究機器學習、深度學習、計算機視覺、智能對話系統相關內容,分享在學習過程中的讀書筆記!期待您的關注,歡迎一起學習交流進步!

知乎主頁:https://www.zhihu.com/people/MicrostrongAI/activities

Github:https://github.com/Microstrong0305

個人博客:https://blog.csdn.net/program_developer

 題目鏈接:

https://www.nowcoder.com/practice/390da4f7a00f44bea7c2f3d19491311b?tpId=13&tqId=11195&tPage=3&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

題目描述:

解題思路:

(1)數組中的數兩兩相加,找出乘積最小的解

時間複雜度爲O(n^2)

已經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)設置兩個指針,時間複雜度O(n)

         例如,輸入數組{1, 2, 4, 7, 11 , 15}和數字15。由於4 + 11 = 15, 因此輸出4和11。

         在面試的時候,很重要的一點是應聘者要表現出很快的反應能力。只要想到一種方法,應聘者就可以馬上告訴面試官,即使這種方法不一定是最好的。比如這個問題,很多人都能立即想到O(n^2)的方法,也就是先在數組中固定一個數字,再依次判斷數組中其餘的 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的數對的過程。

表: 在數組{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循環從兩端向中間掃描數組,因此這種算法的時間複雜度是O(n)

Reference:

【1】《劍指offer》,何海濤著。

【2】https://blog.nowcoder.net/n/0935efd26ade435497dcbe407cfc94ec

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