数组相加和为0
数组中相加和为0的三元组
http://www.nowcoder.com/questionTerminal/345e2ed5f81d4017bbb8cc6055b0b711
分析:考察的数据结构是数组,考察的算法是查找。数组里面的查找除了二分就是双指针了。但是这里要求的是3元。那么我就用3个指针。于是用了 left ,right 作为滑动窗口,mid 在中间寻找。问题转变为如何确定是左边移动还是右边移动?即找到了这样的三元组后哪边指针移动?没找到的话和为什么情况左边移动或者右边移动?我贸然的使用了一些方法,发现总是会有漏网之🐟无法通过。于是找问题,发现我的窗口是一个在缩小的窗口。极端的请况是一边都走完了,但是错过的数据没有办法回溯,于是总是会少一部分3元组。
换换思路:本身暴力的话我需要3个大循环就可以了,假如我在外围固定一个循环,那么剩下的两个循环我换成左右指针不也是一种优化吗?于是思路换成固定一个循环,接下就可以好好的用双指针了。
本题主要考察的是双指针,一些 collection 容器相关的功能可以随便用,比如排序和去重
public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
ArrayList<ArrayList<Integer>> res=new ArrayList<>();
ArrayList<Integer> list=new ArrayList<>();
if(num==null || num.length==0){
return res;
}
if(num.length<3){
return res;
}
Arrays.sort(num); //排序
for(int i=0;i<num.length-1;i++){
int left=i+1;
int right=num.length-1;
while(right-left>=1){
int tmpSum=num[left]+num[right]+num[i];
if(tmpSum==0){
list.add(num[left]);
list.add(num[i]);
list.add(num[right]);
Collections.sort(list);//排序去重
if(!res.contains(list)){
res.add(new ArrayList(list));
}
list.clear();
right--;//找到符合条件的三元组后右指针移动,其实这里左右指针都可以移动的,这里主要是把两个循环变成一个
}else if(tmpSum<0){
left++;
}else {
right--;
}
}
}
return res;
}
查看13道真题和解析