15. 三数之和
这道题的链接: 15. 三数之和
这道题刚一看到,首先想到的肯定是暴力法。。。如果在面对面试官写暴力法,估计就完犊子了,在这里的话,我刚开始想到的是深度优先,但是感觉怪怪的,不过我偷偷看了题解以后,发现可以用双指针来解决这个问题,因为我们可以换个思路,比如首先利用Java的api排个序,然后我们固定一个数,剩下的所有数我们就可以转化成双指针的问题来解决,具体来说就是
- 首先从左往右固定一个数A,当然我们要考虑去重问题(需要添加一个去重操作),如果这个数大于零,那就完犊子,直接return
- 如果这个数A小于零,那么我们就利用双指针,从数A的右边第一个数B和最后一个数C之间的所有数抽取出来做成一个新数列,然后我们从两边一直判断并计算是否B+C=-A,如果存在,就存到List中,一直迭代下去,就可以完成了!!!!
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
for(int k = 0; k < nums.length - 2; k++) {
if(nums[k] > 0) {
break;
}
if(k > 0 && nums[k] == nums[k-1]){
continue;
}
int i = k + 1, j = nums.length - 1;
while(i < j) {
int sum = nums[k] + nums[i] + nums[j];
if(sum < 0) {
while(i < j && nums[i] == nums[++i]);
} else if (sum > 0){
while(i < j && nums[j] == nums[--j]);
} else {
res.add(new ArrayList<Integer>(Array.asList(nums[k],nums[i],nums[j])));
while(i < j && nums[i] == nums[++i]);
while(i < j && nums[j] == nums[--j]);
}
}
}
return res;
}
}
在这里要注意一下,这个简写,可能不好太理解,这里的话就是我们可以这样子理解,&&按照编程原理来说肯定是先看左边为true再看右边,所以注意右边这里是先自增再赋给i,注意哟,最巧的是这里是个while循环,当条件为true的时候,计算循环体里的内容,但是这里没有循环体,所以我们这里就会再次进行while中的判断,我这里想了好久才想通的。
while(i < j && nums[i] == nums[++i]);
也就是说,这里这个循环等价于
while(i < j && nums[i] == nums [i+1]){
i++;
}
换句话说,。这里就是一种去重的功效。