此题是Two Sum的变种,Two Sum能从O(n^2)优化到O(n)。那么此题能从O(n^3)优化到O(n^2)。就是少了那一维n。
此处要注意:1.当有重复的数字时,要跳过;2.找好一个数字去寻找另外两个数字时,只需从右边部分寻找就行,否则会重复。
import java.util.ArrayList; import java.util.Arrays; public class Solution { public ArrayList<ArrayList<Integer>> threeSum(int[] num) { // Start typing your Java solution below // DO NOT write main() function Arrays.sort(num); ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>(); for (int i = 0; i < num.length; i++) { if (i > 0 && num[i] == num[i-1]) continue; int sum = 0 - num[i]; ArrayList<Pair> pairs = getSum(num, sum, i + 1); for (int j = 0; j < pairs.size(); j++) { Pair pair = pairs.get(j); ArrayList<Integer> arr = new ArrayList<Integer>(); arr.add(num[i]); arr.add(pair.x); arr.add(pair.y); ans.add(arr); } } return ans; } // sum is sorted private ArrayList<Pair> getSum(int[] num, int sum, int left) { ArrayList<Pair> ans = new ArrayList<Pair>(); int right = num.length - 1; while (left < right) { if (num[left] + num[right] == sum) { Pair p = new Pair(); p.x = num[left]; p.y = num[right]; ans.add(p); while (left+1 < num.length && num[left] == num[left+1]) { left++; } left++; while (right - 1 >= 0 && num[right] == num[right - 1]) { right--; } right--; } else if (num[left] + num[right] < sum) { left++; } else // (num[left] + num[right] > sum) { right--; } } return ans; } } class Pair { public int x; public int y; }
第二次
class Solution { public: vector<vector<int> > threeSum(vector<int> &num) { vector<vector<int> > result; sort(num.begin(), num.end()); int N = num.size(); for (int i = 0; i < N; i++) { if (i != 0 && num[i] == num[i - 1]) continue; int left = i + 1; int right = N - 1; while (left < right) { if (num[left] + num[right] == -num[i]) { vector<int> tmp; tmp.push_back(num[i]); tmp.push_back(num[left]); tmp.push_back(num[right]); result.push_back(tmp); left++; right--; while (left < right && num[left] == num[left - 1]) left++; while (left < right && num[right] == num[right + 1]) right--; } else if (num[left] + num[right] < -num[i]) { left++; while (left < right && num[left] == num[left - 1]) left++; } else { right--; while (left < right && num[right] == num[right + 1]) right--; } } } return result; } };