三數之和
給定一個包含 n 個整數的數組 nums
,判斷 nums
中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重復的三元組。
注意:答案中不可以包含重復的三元組。
例如, 給定數組 nums = [-1, 0, 1, 2, -1, -4], 滿足要求的三元組集合為: [ [-1, 0, 1], [-1, -1, 2] ]
思路:這道題與兩數之和有一定區別,兩數之和可以直接用list放置,但是三數和這么做時間復雜度過高O(n^2). 因此先將數組排序,得到的有序數組中,設置一個目標target=0-a,然后再對剩下的
兩個數字進行篩選。 遞增數組可以選擇二分查找,兩根指針的方法,此處使用雙指針的方法。
注意點: 由於不包含重復元素,因此要去重。只要有兩個元素重復,則跳過。 代碼如下:
class Solution { List<List<Integer>> res=new ArrayList(); public List<List<Integer>> threeSum(int[] nums) { int len=nums.length; Arrays.sort(nums); for(int i=0;i<len;i++){ if(nums[i]>0)break; //簡化,如果>0則說明該三數之和不可能為0 if(i>0&&nums[i]==nums[i-1])continue; //去重 int target=0-nums[i]; int l=i+1,r=len-1; //此處必須對i后面的數字進行篩選,不能重復 while(l<r){ List<Integer> list=new ArrayList(); if(nums[l]+nums[r]==target){ list.add(nums[i]); list.add(nums[l]); list.add(nums[r]); res.add(list); while(r>l&&nums[l+1]==nums[l])l++; //這個地方改成l-1只會出現一個結果了 while(r>l&&nums[r]==nums[r-1])r--; l++;r--; }else if(nums[l]+nums[r]>target)r--; else l++; } } return res; } }
總結:思路並不是很復雜,但是這道題很完美的體現了算法題對於邊界條件和對邏輯的嚴格要求,
每一步的每一個符號都能影響最終結果。 因此做算法題的時候思路一定要保持清晰,確保
邏輯的正確性。與初級算法比較,中級算法要求的思維更加嚴謹。
清晰