1. 程式人生 > 其它 >Python面試題:兩數之和

Python面試題:兩數之和

技術標籤:筆記

兩數之和問題是會在面試中出現:

該定一個整數陣列nums和一個目標值target,請在該陣列中找出和為目標值的那兩個整數,並返回他們的陣列下標。你可以假設某種輸入只會對應一個答案。但是,你不能重複利用這個陣列中同樣的元素。

示例:
給定nums=[2,7,11,15],target=9
因為nums[0]+nums[1]=2+7=9
所以返回[0,1]

儘管這是一個看似簡單的問題,但是你可以採取多種方法,沒種方法都有自己的優點與缺點。

方法一:基本方法

只需要遍歷所有可能的數字對,然後返回第一對,它們的總和就是你想要的。

  def two_sum(arr,sum_val):
       for i in range(len(arr)):
           for j in range(i,len(arr)):
                if arr[i]+arr[j]==sum_val:
                    return [i,j]
       return None

這種方法在O(n²)時間和O(1)的空間中執行,其中是arr的長度。

方法二:優化時間

第二種方法通過使用額外的空間來提高時間複雜度。

首先初始化一個空對映,它將用於儲存之前的元素及其索引。

然後,對於列表中的每個元素,首先通過檢查“sum val-current”是否在對映的鍵集中,來檢查之前是否遇到過sum val-current。如果是,那麼你已經找到了所需的對,因current_element+(sum_val-current_element)==sum_val。

否則,將current_element新增到對映中,然後移動到下一個元素。

 def two_sum(arr,sum_val):
     seen={}
     for i in range(len(arr)):
         if  sum_val - arr in seen:
             return [i,seen[sum_val - arr]]
         else:
             seen[arr[i]]=  i
     return None

這種方法在O(n)時間和O(n)空間中執行。在這裡,我們只訪問每個陣列元素一次,因為我們將以前看到的元素及其索引快取在了對映中。

方法三:優化空間
最後一種方法在不用額外空間的情況下提高了時間複雜度,但是仍然比方法2使用更多時間。

在這種方法中,我們首先對陣列進行排序,並使用排序陣列的屬性來提高時間複雜度,而不需要使用輔助空間。

為此,我們將使用一個雙指標方法。我們在第一個元素出開始一個指標,在最後一個元素處開始第二個指標。然後檢查指標所指向的兩個元素的和。

如果和太大,則遞減第二個指標,如果和太小,則遞減第一個指標。

因為陣列是排序的,所以我們可以保證陣列是不會減少的。

def  two_sum(arr,sum_val):
    arr_sorted = sorted(arr)
    left=0
    right = len(arr) - 1
    targets = None
   
    while left < right:
        cur_sum=arr_sorted[left]+arr_sorted[right]
        if cur_sum == sum_val:
            targets=[left,right]
            break
        elif  cur_sum > sum_val:
            right=right - 1
        else:
            left=left+1
    if not targets:
        return None

  return[
      arr.index(arr_sorted[targets[0]]),
      arr.index(arr_sorted[targets[1]])
  ]

這種方法在O(nlog(n))時間和O(1)空間中執行。這裡我們假設使用的排序方法在O(nlog(n))時間和O(1)空間中執行,比如堆序列。

☆注意,此方法執行時的主要原因來自排序操作。之後進行O(n)比較,因為指標每次移動1,直到他們重疊為止。

在這裡,我們改進了基本方法的時間複雜度,而不需要像方法2那樣使用額外的儲存。我們可以利用陣列已排序的事實來最小化我們必須進行比較的數量。