一、题目:三数之和
二、题目解析:
题目解析:从数组里面找到三个数,并且相加等于0,同时答案里不能有相同的数组。
难点:每次循环开始和找到一个结果后都需要判断和前一个元素是否相等去重问题。
解题步骤:
- 给数组排序
- 遍历数组,从0遍历到length-2(为甚么?) 防止下标越界<length-2 如果i在倒数第二个元素,start = i+1 ,end没地方放了
- 如果当前的数字等于前一个数字,则跳过这个数(为甚么?) 主要为了去重
- 如果数字不同,则设置start = i+1,end=length-1,查看i,start和end,三个数的和比零大还是小,如果比0小,start++,如果比0大,end–,如果等于0,把三个数加入到结果里。
- 返回结果
图示帮助理解:
三、代码如下:
public List<List<Integer>> threeSum(int[] nums) {
ArrayList<List<Integer>> result = new ArrayList<List<Integer>>();
Arrays.sort(nums); //排序
for (int i = 0; i < nums.length - 2; i++) { //防止越界,因为这里需要放入三个指针
if (i == 0 || nums[i] != nums[i - 1]) { // i是第一个不用和前面的数比较[因为没有],或者新的数和原来的数不相等,才需要循环,相等不需要处理,否则会产生重复的结果
int start = i + 1, end = nums.length - 1;//定义两个变量
while (start < end) { //start<end的情况下判断它们相加的和 start和end相等时循环退出
if (nums[i] + nums[start] + nums[end] == 0) { //第一种结果等于0
result.add(Arrays.asList(nums[i], nums[start], nums[end])); //说明找到结果,放入结果集中
start++;
end--;
//难点来了 添加结果后,缩进start 和 end的时候 又要判断start和end和之前所在的位置是否是一样的,一样的话又会产生重复的字符,需要仔细想一想
while (start < end && nums[start] == nums[start - 1]) { //循环到旧的start和新的start不相等位置,end也是同样操作
start++;
}
while (start < end && nums[end] == nums[end + 1]) { //end是从右往左,所以需要判断+1
end--;
}
} else if (nums[i] + nums[start] + nums[end] < 0) { //第二种情况小于0
start++; //小于0时,需要让和更大
} else { //第三种情况大于0
end--; //大于0时,需要让和更小
}
}
}
}
return result;
}
四、测试
五、结束