三数之和

Source

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

思路:

首先对数组排序,使用快排。然后用一个for来遍历数组,首先判断该数是否大于0,如果大于0,那么就直接break掉,因为后面的数加起来不可能等于0;如果小于0,首先计算target = 0 - nums[i]的值,然后在[i+1,nums.length - 1]中扫描,找到和为target的数字。

方法:

使用类似快排的方法来进行扫描:

  • 设置前后两个指针k和j
  • 如果nums[i]+nums[j] == target,把nums[i],nums[k],nums[j]依次放入list中,然后k++,j--。
  • 如果nums[i]+nums[j] > target,j--
  • 如果nums[i]+nums[j] < target,k--

代码:

 public static List<List<Integer>> threeSum(int[] nums) {

        List<List<Integer>> result = new ArrayList<>();
        Set<List<Integer>> set = new HashSet<>();
        if (nums.length < 3){
            return result;
        }
        sort(nums,0,nums.length - 1);
        int target,k,j;
        for (int i = 0; i < nums.length -2; i++){
            if (nums[i] >0){
                break;
            }else {
                target = 0 - nums[i];
                k = i + 1;
                j = nums.length - 1;
                while (k < j){
                    int s = nums[k] + nums[j];
                    if (s == target){
                        List<Integer> temp = new ArrayList<>();
                        temp.add(nums[i]);
                        temp.add(nums[k]);
                        temp.add(nums[j]);
                        set.add(temp);
                        k++;
                        j--;
                    }else if (s > target){
                        j --;
                    }else {
                        k ++;
                    }
                }
            }
        }

        result.addAll(set);
        return result;
    }

    /**
     *     快速排序
     */
    public static void sort(int[] a,int low,int high ){
        int start = low;
        int end = high;
        int key = a[low];

        if (high > low ) {
            while (start != end) {
                while (end > start && a[end] >= key) {
                    end --;
                }
                if (start < end) {
                    a[start] = a[end];
                    start ++;
                }
                while (end > start && a[start] <= key) {
                    start ++;
                }
                if (start < end) {
                    a[end] = a[start];
                    end --;
                }

            }
            a[start] = key;

            if (start - 1 >= 0) {
                sort(a, low, start - 1);
            }
            if (start + 1 < high) {
                sort(a, start + 1, high);
            }
        }
    }