leetcode -- 15. 3Sum 【問題轉化2sum + 避免重複計算的方法(規定次序)】
阿新 • • 發佈:2019-01-08
題目
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note: The solution set must not contain duplicate triplets.
For example, given array S = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
題意
在給定的陣列S中尋找3個數的和為0的情況。
分析及解答
- 【轉化】 將 3sum 轉化為2sum的問題進行處理,即 固定一個 數,然後去按照2sum的方式進行處理。
- 【避免重複計算】為了避免一些不必要的元素重複加入到結果集中,我們需要適當的限定遍歷的次序。(程式碼中標號3的註釋部分)
程式碼
class Solution { public List<List<Integer>> threeSum(int[] nums) { //1.排序。 Arrays.sort(nums); //2.選取c(不同於上次所選),然後 尋找a,b 滿足 a + b = -c。 //3.a,b,c記錄放入的集合S.(如何做到不重複放入呢?規定次序:只能在c的右邊空間中尋找) List<List<Integer>> results = new ArrayList<>(); int c = 0; for(int i = 0 ; i < nums.length ; i++){ if(i == 0){ c = nums[i]; }else if(nums[i] == c){ continue; }else{ c = nums[i]; } for(int p1 = i+1,p2= nums.length -1 ;p1 < p2;){ if(nums[p1] + nums[p2] + c == 0){ //加入結果集中。 List<Integer> result = new ArrayList<>(3); result.add(c); result.add(nums[p1]); result.add(nums[p2]); results.add(result); while(p1 < p2 && nums[p1] == nums[++p1]){ // 這裡出現了一些bug,注意。 } while(p1 < p2 && nums[p2] == nums[--p2]){ } }else if(nums[p1] + nums[p2] + c < 0){ p1++; }else if(nums[p1] + nums[p2] + c > 0){ p2--; } } } return results; } }