描述:給你乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?請你找出所有滿足條件且不重複的三元組。
注意:答案中不可以包含重複的三元組。
示例:
給定陣列 nums = [-1, 0, 1, 2, -1, -4],解答:滿足要求的三元組集合為:
[[-1, 0, 1],
[-1, -1, 2]
]
class
solution
else
if(nums[left]
+nums[right]
>
-nums[i]
)else}}
return result;
}}
思路:
三數之和為0,即找到三個數滿足a+b+c=0。那麼可以轉換成a+b=-c,即將三數問題轉換為兩數問題。
先將陣列排序。然後從左向右遍歷陣列,將每一次遍歷的數當作c,然後在當前遍歷中對這個數之後的數列使用雙指標來找a和b滿足a+b=-c。
雙指標得確定指標的移動規則:
if
(nums[左指標]
+nums[右指標]
=-c)
else
if(nums[左指標]
+nums[右指標]
>
-c) 右指標減一; //這是為了讓結果逼近-c,下面同理
else
if(nums[左指標]
+nums[右指標]
<
-c) 左指標加一;
由於答案中要求不能出現重複的三元組,所以光有了指標的移動規則還不夠,去重也是很重要的一部分。
if
(i>
0&&nums[i]
==nums[i-1]
)continue
;
這行**首先是對a+b=-c中的c去重。每一次遍歷向前找是否有相同的數。我之前的思路是向後找相同以去重,即if(nums[i]==nums[i+1]) continue;
但這就大錯特錯了,因為向後找的話,當遍歷遇到一段由相等數字組成的數列段時,會直接從這一段的最後乙個數字開始遍歷。而向前找相同就能保證遇到一段由相等數字組成的數列段時,能使這一段的第乙個數字被遍歷到。
while
((left&&(nums[left]
==nums[left+1]
))left++
;while
((left&&(nums[right]
==nums[right-1]
))right--
;
a+b=-c中a和b的去重。首先明確,要對乙個數進行去重的基本條件是,我不需要這個數了,那麼在nums[left]+nums[right]==-nums[i]
條件下,由於答案不能是重複的三原組,因此nums[left]
和nums[right]
都是不再需要的數,所以對nums[left]
和nums[right]
進行去重。在nums[left]+nums[right]>-nums[i]
條件下,由於此時要將nums[left]+nums[right]
逼近-nums[i]
,因此左指標加一,即不需要nums[left]
,所以對nums[left]
去重。同理nums[left]+nums[right]<-nums[i]
條件下的去重。 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 分析排序 雙指標避免...