leetcode題解 第15題3 Sum

2021-10-08 07:41:38 字數 2841 閱讀 8115

這道題與two sum很像,我們很容易想到利用two sum的程式來解答這個問題,對於a+b+c = 0,有-c = a+b,這相當於target設定為-c的two sum問題。區別在於,a和b的值不是唯一的,即這個two sum的答案不唯一。

除了找到所有正確的a和b外,還要解決三元組重複的問題。

我們依然考慮在two sum的基礎上解決這個問題。

首先,two sum的核心**是:

for

(int i =

0; i < nums.

size()

;++i)

; m[nums[i]

]= i;

}

我們把return那一行做一些修改,改為新增乙個三元組到答案中,就可以作為本題的核心**了。

問題在於,這樣做會導致大量重複的三元組,有兩種情況的重複:

調換元素順序導致的重複:如[-1,0,1]和[0,-1,1]本質上是同乙個三元組

不同元素的值相同導致的重複:如nums=[-4,2,2,2],會導致兩個[-4,2,2]的產生;nums=[-1,-1,0,1],會導致兩個[-1,0,1]的產生

情況1比較容易解決,我們在新增三元組時,只新增a <= b <= c這樣的[a,b,c]到答案中,即指定答案中三元組的順序。

但這樣做是不夠的,不僅解決不了情況2,當多個元素值相同時,連情況1也解決不了。如nums=[0,0,0],這時滿足a == b == c,我們加的限制條件也就沒有用了。

採用排序的方法能夠很好地解決這兩種情況的重複。

對於排序之後的陣列,我們使用雙層迴圈,外層迴圈用於尋找target值,內層迴圈的邏輯就是two sum的邏輯,借助雜湊表來尋找sum為target的兩個元素。

我們保證內層迴圈列舉到的元素不小於外層迴圈的元素,就可以解決情況1。對於每重迴圈還要保證相鄰兩次遍歷到的元素值不相同,這是為了解決情況2。偽**如下:

nums.

sort()

for i =0..

.n-1

if i >

0&& nums[i]

== nums[i-1]

continue

;for j = i+1..

.n-1

if j > i+

1&& nums[j]

== nums[j-1]

continue

;// a=nums[j], 用雜湊表找對應的b

需要注意的是,如果我們像two sum中那樣一邊遍歷一邊向雜湊表中插入元素,可以滿足a <= b <= c,即解決情況1。因為在遍歷到b時target-b還不在雜湊表中,而遍歷到c時target-c在雜湊表中。

這樣做貌似效率很高,但會錯過[-4,2,2]這樣的三元組。因為當j == 1時nums[j]不在雜湊表中,而j=2時又因為nums[j] == nums[j-1],不會參與判斷。我們為了去除重複結果矯枉過正了。解決辦法是在排序之後先將陣列元素插入雜湊表中。

我們增加了乙個判斷條件m[sum - nums[j]] > j來保證a <= b <= c。對於[-4,2,2]這種元素有相同值的情況,也是滿足的,因為經過排序後最終覆蓋雜湊表的肯定是index最大的那個元素。最終,我們要新增的三元組是[nums[i], nums[j], nums[m[target - nums[j]]]]

**

class solution );

}}}return result;}}

;

複雜度分析

時間複雜度o(n

2)

o(n^2)

o(n2

),空間複雜度o(n

)o(n)

o(n)

。注意用的排序演算法時間複雜度o(n

logn

)o(nlogn)

o(nlog

n)。去除重複三元組的思路與解法一相同,但我們不使用雜湊表,而是使用雙指標來優化暴力解法。

暴力解法是3重迴圈,同時滿足兩個條件:

內層遍歷迴圈元素不小於外層迴圈遍歷的元素

對於每一重迴圈,相鄰遍歷的元素值不相同

即解法一中的核心想法。

3重迴圈獲取到a,b,c,如果a+b+c = 0,它們就是乙個滿足條件的三元組。自然,a,b對應唯一的c,當b增大時,c減小,因此,我們可以在從左往右列舉b的同時從右往左列舉c

當a+b+c > 0時,把右指標向左移動,取更小的c

當a+b+c = 0時,把左指標向右移動,取更大的b,此時肯定有a+b+c > 0

當a+b+c < 0時,可以確定這個a,b沒有對應的c,把左指標向右移動,取更大的b。是否要把右指標向右移動呢?不用。首先要明白為什麼會有a+b+c < 0出現,肯定因為1.導致的,如果我們又把右指標往右移,那麼又會得到a+b+c > 0的結果,最終還得把右指標移到現在這位置來

這樣一來,就可以把第二重和第三重迴圈壓縮成乙個迴圈了。當然,始終要保證b <= c,否則退出迴圈。

**

class solution );

}}}return result;}}

;

複雜度分析

時間複雜度o(n

2)

o(n^2)

o(n2

),空間複雜度o(l

ogn)

o(logn)

o(logn

),排序的空間複雜度為o(l

ogn)

o(logn)

o(logn

)。

LeetCode第15題解析

給你乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c 使得 a b c 0 請你找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。示例 給定陣列 nums 1,0,1,2,1,4 滿足要求的三元組集合為 1,0,1 1,1,2 class so...

LeetCode第3題題解 無重複字元的最長子串

題目 leetcode 題目描述 給定乙個字串,請你找出其中不含有重複字元的最長子串的長度。示例 1 輸入 abcabcbb 輸出 3 解釋 因為無重複字元的最長子串是 abc 所以其長度為 3。示例 2 輸入 bbbbb 輸出 1 解釋 因為無重複字元的最長子串是 b 所以其長度為 1。示例 3 ...

LeetCode第15題 三數之和

給定乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c 使得 a b c 0 找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。例如,給定陣列 nums 1,0,1,2,1,4 滿足要求的三元組集合為 1,0,1 1,1,2 思路 首先想到的肯定...