此题是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;
}
};