15. 三数之和

这道题的链接: 15. 三数之和
这道题刚一看到,首先想到的肯定是暴力法。。。如果在面对面试官写暴力法,估计就完犊子了,在这里的话,我刚开始想到的是深度优先,但是感觉怪怪的,不过我偷偷看了题解以后,发现可以用双指针来解决这个问题,因为我们可以换个思路,比如首先利用Java的api排个序,然后我们固定一个数,剩下的所有数我们就可以转化成双指针的问题来解决,具体来说就是

  1. 首先从左往右固定一个数A,当然我们要考虑去重问题(需要添加一个去重操作),如果这个数大于零,那就完犊子,直接return
  2. 如果这个数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++;
}

换句话说,。这里就是一种去重的功效。