15 三數之和

2021-10-13 13:15:32 字數 3264 閱讀 5055

solution/san-shu-zhi-he-by-leetcode-solution/

題目要求:

給你乙個包含n個整數的陣列nums,判斷nums中是否存在三個元素abc,使得a + b + c = 0,請你找出所有滿足條件且不重複的三元組。

注意:答案中不可以包含重複的三元組。

示例:

給定陣列 nums = [-1, 0, 1, 2, -1, -4],

滿足要求的三元組集合為:

[ [-1, 0, 1],

[-1, -1, 2]

]

暴力匹配

暴力匹配可以,三層for迴圈帶給我們的是 o(n3) 的複雜度,我們還需要將三個數按照從小到大的順序排列,並使用hashmap進行去重操作,得到不包含重複三元組的最終答案

因為(a, b, c)(b, a, c)(b, c, a)屬於重複的三元組,匹配之後我們需要進行排序、去重操作

排序 + 雙指標

我們首先要理解不重複的本質是什麼?我們先將陣列排序,然後在陣列中找出三個數abc,滿足其和:a + b + c = 0,其中a <= b <= c,這樣保證了只有(a, b, c)這樣的順序,不會出現(b, a, c)或者(b, c, a)這樣的順序,這樣我們就不用對三元組進行去重操作

但是這樣做我們始終沒有跳出三層for迴圈的思想,實際上第二重 + 第三重迴圈我們可以使用一層while迴圈 + 雙指標來替代

left = i + 1為左指標(i最外層for迴圈的計數器),right = nums.length - 1為右指標。當left增加,right不變時,三數之和增大;當right減小,left不變時,三數之和減小;我們利用這個特點,可以將原來兩層for迴圈變為一層while迴圈,即我們可以通過雙指標的方式將內層迴圈的複雜度從 o(n2) 降為 o(n)

為了保證得到的三元組為不重複的三元組,對於數a,我們每次在for迴圈中都判斷數a是否與上次的值相同,如果相同,則跳過本次迴圈,對於leftright,我們每次在外層for開始時,將left重置為i + 1,將right重置為nums.length - 1,在匹配到三數之和等於0時,將left右移至與上次元素值不同的位置,將right左移至與上次元素值不同的位置(保證三元組不重複)

總結:

題目要求不可以包含重複的三元組,我們可以使用模式識別,利用排序避免重複答案

將陣列排序後,進入第一層for迴圈之後其實就是twosum問題,與twosum不同的是,twosum只需要找到一組解,而這裡要找到所有解 ,從而將問題變為:在乙個排序陣列中找到所有的兩數之和

在乙個排序陣列中找到所有的兩數之和:兩個指標分別指向陣列的首位,如果sum > target,那麼首指標後移,使得sum增大;如果sum < target,那麼尾指標前移,使得sum減小

**

/**

* @classname threesumdemo

* @description todo

* @author heygo

* @date 2020/9/2 17:11

* @version 1.0

*/public

class

threesumdemo);

system.out.

println

(res);}

public

static list

>

threesum

(int

nums)

// 先對陣列進行排序,後面才能方便地進行判斷是否重複

arrays.

sort

(nums)

;// 遍歷陣列,當 i = nums.length - 3時,left = nums.length - 2,right = nums.length - 1,為臨界條件

for(

int i =

0; i < nums.length -

2; i++

)// 上一次的元素和當前相同,跳過此次迴圈

if(i >

0&& nums[i]

== nums[i -1]

)int target =

-nums[i]

;// 目標值

int left = i +1;

// left 指標

int right = nums.length -1;

// right 指標

// 當 left < right 時,證明還有元素待驗證

while

(left < right)

// 右指標需要移動至下乙個與上次元素值不相同的位置

while

(left < right && nums[right]

== nums[right +1]

)}else

if(nums[left]

+ nums[right]

< target)

else}}

return result;

}}

15 三數之和

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

15 三數之和

給定乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c 使得 a b c 0 找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。有兩種寫法 第一種耗時久,但容易解讀 class solution if nums.length 3 else if ...

15 三數之和

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