三数之和 vs 四数之和

三数之和

四数之和

为了避免枚举到重复四元组,则需要保证每一重循环枚举到的元素不小于其上一重循环枚举到的元素,且在同一重循环中不能多次枚举到相同的元素。

为了实现上述要求,可以对数组进行排序,并且在循环过程中遵循以下两点:

  • 每一种循环枚举到的下标必须大于上一重循环枚举到的下标;
  • 同一重循环中,如果当前元素与上一个元素相同,则跳过当前元素。
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if (nums == null || nums.length < 3) {
            return res;
        }
        int len = nums.length;
        Arrays.sort(nums);

        for (int i = 0; i < len-2; i++) {
            // 同一层循环中,避免重复使用相同元素
            if (i > 0 && nums[i] == nums[i-1]) {
                continue;
            }
            // 剪枝处理
            if (nums[i] + nums[i+1] + nums[i+2] > 0) {
                break;
            }
            if (nums[i] + nums[len-1] + nums[len-2] < 0) {
                continue;
            }

            // 双指针枚举第二和第三个元素
            int left = i+1, right = len-1;
            while (left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum == 0) {
                    res.add(Arrays.asList(nums[i], nums[left], nums[right]));

                    while (left < right && nums[left] == nums[left+1]) {
                        left++;
                    }
                    left++;

                    while (left < right && nums[right] == nums[right-1]) {
                        right--;
                    }
                    right--;
                } else if (sum > 0) {
                    right--;
                } else {
                    left++;
                }
            }
        }

        return res;
    }
}
class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if (nums == null || nums.length < 4) return res;
        int len = nums.length;
        Arrays.sort(nums);

        for (int i = 0; i < len-3; i++) {
            // 避免重复
            if (i > 0 && nums[i] == nums[i-1]) {
                continue;
            }
            // 剪枝操作
            if (nums[i] + nums[i+1] + nums[i+2] + nums[i+3] > target) {
                break;
            }
            if (nums[i] + nums[len-1] + nums[len-2] + nums[len-3] < target) {
                continue;
            }

            for (int j = i+1; j < len-2; j++) {
                // 避免重复
                if (j > i+1 && nums[j] == nums[j-1]) {
                    continue;
                }
                // 剪枝操作
                if (nums[i] + nums[j] + nums[j+1] + nums[j+2] > target) {
                    break;
                }
                if (nums[i] + nums[j] + nums[len-1] + nums[len-2] < target) {
                    continue;
                }

                int left = j+1, right = len-1;
                while (left < right) {
                    int sum = nums[i] + nums[j] + nums[left] + nums[right];
                    if (sum == target) {
                        res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));    // 将array转换为List
                        while (left < right && nums[left] == nums[left+1]) {
                            left++;
                        }
                        left++;
                        while (left < right && nums[right] == nums[right-1]) {
                            right--;
                        }
                        right--;
                    } else if (sum < target){
                        left++;
                    } else {
                        right--;
                    }
                }
            }
        }
        return res;
    }
}

 

posted @ 2021-09-21 11:36  Peterxiazhen  阅读(46)  评论(0编辑  收藏  举报