题解 | #数组中相加和为0的三元组#
数组中相加和为0的三元组
http://www.nowcoder.com/practice/345e2ed5f81d4017bbb8cc6055b0b711
首先,我们先对数组进行排序处理。
然后,确定固定指针i,与双指针j,k。其中固定位从0开始,j从i起始的下一位向左移动,k从数组末端向右移动。
①提前结束的条件 num[i]>0
因为i < j < k,所以num[i]>=num[j]>=num[k]。因此如果num[i]>0,不可能使三个大于0的数之和等于0
②重复数字跳过
在有序数组中,如果遍历当相邻位的值相同,直接跳过。
③循环流程
如果三数之和sum>0,k向左移动
如果sum<0,j向右移动
如果sum == 0,记录i、j、k
i、j继续移动寻找当前固定指针下的其他解,直到左右指针碰撞结束循环。
固定指针向前移动,并开始新循环。
固定指针时间复杂度O(N),移动指针ij时间复杂度O(N),嵌套之后时间复杂度O(N)
import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
public ArrayList<ArrayList<Integer>> threeSum(int[] num) {'
//先对数组进行排序
Arrays.sort(num);
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
for(int i=0; i<num.length-2; i++){
int j = i + 1, k = num.length - 1;
//如果固定位大于0,已经不可能找到三数和为0的数,提前退出
if(num[i] > 0)break;
//如果相邻数重复,直接跳过
if(i > 0 && num[i] == num[i-1])continue;
while(j < k){
int sum = num[i] + num[j] + num[k];
if(sum > 0){
while(j < k && num[k] == num[--k]);
}
else if(sum < 0){
while(j < k && num[j] == num[++j]);
}
else{
res.add(new ArrayList<Integer>(Arrays.asList(num[i], num[j], num[k])));
while(j < k && num[k] == num[--k]);
while(j < k && num[j] == num[++j]);
}
}
}
return res;
}
}