計(jì)算機(jī)科學(xué)中哨毁,題“兩數(shù)之和”乃經(jīng)典。
旨在給定一個(gè)整數(shù)數(shù)組和一個(gè)目標(biāo)值椅亚,找出數(shù)組中和為目標(biāo)值的兩個(gè)整數(shù)限番,并返回它們的數(shù)組下標(biāo)。這個(gè)問(wèn)題看似簡(jiǎn)單呀舔,卻蘊(yùn)含著多種解題思路和算法技巧弥虐。本文將探討幾種解決兩數(shù)之和問(wèn)題的方法,并分析其時(shí)間復(fù)雜度和空間復(fù)雜度。
#### 暴力法
最直觀的解決方法是使用雙循環(huán)遍歷整個(gè)數(shù)組霜瘪,對(duì)于每一個(gè)元素珠插,遍歷其后的所有元素,尋找與目標(biāo)值相等的組合颖对。這種方法的時(shí)間復(fù)雜度為$O(n^2)$捻撑,其中$n$是數(shù)組的長(zhǎng)度。雖然簡(jiǎn)單易懂缤底,但在面對(duì)大規(guī)模數(shù)據(jù)時(shí)效率低下顾患,容易超時(shí)。
```
def twoSum(nums, target):
? ? for i in range(len(nums)):
? ? ? ? for j in range(i + 1, len(nums)):
? ? ? ? ? ? if nums[i] + nums[j] == target:
? ? ? ? ? ? ? ? return [i, j]
? ? return []
```
#### 哈希表法
為了優(yōu)化時(shí)間復(fù)雜度训堆,可以使用哈希表來(lái)存儲(chǔ)數(shù)組中的元素描验。在遍歷數(shù)組時(shí),對(duì)于每一個(gè)元素坑鱼,通過(guò)哈希表查找是否存在另一個(gè)元素膘流,使其與當(dāng)前元素之和等于目標(biāo)值。由于哈希表的查找操作平均時(shí)間復(fù)雜度為$O(1)$鲁沥,因此這種方法的時(shí)間復(fù)雜度為$O(n)$呼股,大大提高了效率。
```
def twoSum(nums, target):
? ? hashmap = {}
? ? for index, num in enumerate(nums):
? ? ? ? another_num = target - num
? ? ? ? if another_num in hashmap:
? ? ? ? ? ? return [hashmap[another_num], index]
? ? ? ? hashmap[num] = index
? ? return []
```
#### 一次遍歷哈希表優(yōu)化
在哈希表法的基礎(chǔ)上画恰,還可以進(jìn)一步優(yōu)化彭谁,使得在遍歷數(shù)組的同時(shí)進(jìn)行哈希表的構(gòu)建和查找。具體來(lái)說(shuō)允扇,在遍歷數(shù)組時(shí)缠局,對(duì)于每一個(gè)元素,先在哈希表中查找是否存在另一個(gè)元素使其與當(dāng)前元素之和等于目標(biāo)值考润,如果存在則直接返回結(jié)果狭园;如果不存在,則將當(dāng)前元素存入哈希表中糊治。這樣可以確保在遍歷過(guò)程中唱矛,每一個(gè)元素只會(huì)被訪問(wèn)一次。
```
def twoSum(nums, target):
? ? hashmap = {}
? ? for i, num in enumerate(nums):
? ? ? ? if target - num in hashmap:
? ? ? ? ? ? return [hashmap[target - num], i]
? ? ? ? hashmap[num] = i
? ? return []
```
#### 二分查找法(針對(duì)有序數(shù)組)
如果給定數(shù)組是有序的井辜,還可以使用二分查找的方法來(lái)優(yōu)化解決過(guò)程绎谦。具體來(lái)說(shuō),對(duì)于數(shù)組中的每一個(gè)元素粥脚,通過(guò)二分查找在其后的元素中尋找另一個(gè)元素窃肠,使其與當(dāng)前元素之和等于目標(biāo)值。由于二分查找的時(shí)間復(fù)雜度為$O(log n)$阿逃,因此這種方法的時(shí)間復(fù)雜度為$O(n \log n)$铭拧,比暴力法更優(yōu)赃蛛。
```
def twoSum(nums, target):
? ? for i in range(len(nums)):
? ? ? ? low, high = i + 1, len(nums) - 1
? ? ? ? while low <= high:
? ? ? ? ? ? mid = (low + high) // 2
? ? ? ? ? ? if nums[mid] == target - nums[i]:
? ? ? ? ? ? ? ? return [i, mid]
? ? ? ? ? ? elif nums[mid] < target - nums[i]:
? ? ? ? ? ? ? ? low = mid + 1
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? high = mid - 1
? ? return []
```
#### 總結(jié)
兩數(shù)之和問(wèn)題雖然簡(jiǎn)單恃锉,卻可以通過(guò)多種算法思路來(lái)解決搀菩,從暴力法到哈希表法,再到針對(duì)有序數(shù)組的二分查找法破托,每一種方法都有其獨(dú)特的時(shí)間復(fù)雜度和適用場(chǎng)景肪跋。在實(shí)際應(yīng)用中,應(yīng)根據(jù)具體問(wèn)題的特點(diǎn)選擇最合適的算法土砂,以達(dá)到最優(yōu)的效率和性能州既。