solution/san-shu-zhi-he-by-leetcode-solution/
題目要求:給你乙個包含
n
個整數的陣列nums
,判斷nums
中是否存在三個元素a
,b
,c
,使得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)
屬於重複的三元組,匹配之後我們需要進行排序、去重操作
排序 + 雙指標
我們首先要理解不重複的本質是什麼?我們先將陣列排序,然後在陣列中找出三個數a
、b
、c
,滿足其和: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
是否與上次的值相同,如果相同,則跳過本次迴圈,對於left
和right
,我們每次在外層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 分析排序 雙指標避免...