給你乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?請你找出所有滿足條件且不重複的三元組。
注意:答案中不可以包含重複的三元組。
示例:給定陣列 nums = [-1, 0, 1, 2, -1, -4],
滿足要求的三元組集合為:
[[-1, 0, 1],
[-1, -1, 2]
]如果是陣列是有序的,則可以用雙指標以線性時間複雜度來遍歷所有滿足題意得兩個數組合;
現對原陣列進行排序sort(num.begin(),num.end())
,預設是增序排列;然後開始遍歷排序後的陣列,這裡注意不是遍歷到最後乙個停止,而是到倒數第三個就可以了(why?因為這裡遍歷的是第乙個要固定的數,還要留兩個作為同一組求和數)
這裡可以做個剪枝優化,第乙個要fix的書為正數的話,則後面的數字就都是正數,永遠不會出現和胃0的情況;還要加上重複就跳過的處理; 處理的方法是,從第二個數開始,如果和前面的數字相等,就跳過,因為不想把相同的數字fix兩次,這裡可以做個map,進行過濾;
對於遍歷到的數,用0減去這個fix數,得到我們要找的target(相反數,剩下我們要找兩數之和等於相反數)即可; 用兩個指標,分別指向fix數字之後開始的首尾兩個數,如果兩數之和正好為target,則將這兩個數和fix的數一起存入結果中。然後就是跳過重複數字的步驟了,兩個指標都要檢測重複數字。如果兩數之和小於target,則將左邊的那個指標i 右移一位,使得兩數之和增大一些; 如果比target大,則把右邊指標j左移一位,使得兩數之和減小一些;
解題思路**於:
vectorint>>
threesum
(vector<
int>
& nums)
; vectorint>> res;
// 用set 儲存 fix過的第乙個數 ,一維的無重複陣列用 set, 二維的用map
std::set<
int> processed;
// 這裡(int)nums.size() 強轉為int 因為nums.size() 返回值為 unsigned型,如果nums.size()為1,此時 1-2=-1,對於無符號數來說相當於正數,0還是會小於正數的,這時候就會越界
for(
int m =
0; m <
(int
)nums.
size()
-2; m++
)else
int target =
0- nums[m]
, i = m +
1, j = nums.
size()
-1;;
while
(i < j));
// 排除nums[i] = nums[i+1] 和 nums[j] = nums[j - 1] 的情況
// 具體見用例 [-2,0,0,2,2]
while
(i < j && nums[i]
== nums[i +1]
)++i;
while
(i < j && nums[j]
== nums[j -1]
)--j;
i++; j--;}
else
if(sum < target)
else}}
}return res;
}
求三數之和
給你乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c 使得 a b c 0 請你找出所有滿足條件且不重複的三元組。示例 給定陣列 nums 1,0,1,2,1,4 滿足要求的三元組集合為 1,0,1 1,1,2 思路 先對陣列nums進行排序,設定len為陣列長度...
15 三數之和 3Sum
給定乙個包含 n 個整數的陣列nums,判斷nums中是否存在三個元素 a,b,c 使得 a b c 0 找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。例如,給定陣列 nums 1,0,1,2,1,4 滿足要求的三元組集合為 1,0,1 1,1,2 線性複雜度 class s...
演算法 三數之和(3sum)。
給你乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c 使得 a b c 0 請你找出所有滿足條件且不重複的三元組。注意 答案中不可以包含重複的三元組。給定陣列 nums 1,0,1,2,1,4 滿足要求的三元組集合為 1,0,1 1,1,2 本題與兩數之和類似,是...