LeetCode18:四数之和

Posted mx_info

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode18:四数之和相关的知识,希望对你有一定的参考价值。

LeetCode18:四数之和

题目描述

/**
     * 给定一个包含 n 个整数的数组 nums 和一个目标值 target,
     * 判断 nums 中是否存在四个元素 a,b,c 和 d ,
     * 使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
     * <p>
     * 注意:答案中不可以包含重复的四元组
     */

思路分析

  1. 使用排序 + 双重遍历 + 双指针的思路
  2. 使用外层循环从左到右遍历一次数组元素,因为至少要保证四个数求和,因此第一层遍历只需要循环 len - 3次即可
  3. 使用内层循环从第一次遍历的右一个下标开始遍历,保证数组中所有情况都能考虑到
  4. 使用排序,可以方便两指针的移动
  5. 使用左指针指向内层循环的右侧一个元素,右指针指向倒数第一个元素,则可以根据四个数的和与target 的关系移动左右指针
  6. 因为要求不包含重复元素,则可以使用hash结构去重,将去重后的元素序列添加
  7. 考虑优化: 可以判断四个数的和 的最大值或者最小值与target的关系,提前结束此次循环

源码及分析

//思路分析
    //1. 使用排序 + 双重循环 + 双指针
    public List<List<Integer>> fourSum(int[] nums, int target) {
        //数据校验:如果nums为空或者长度小于4,返回空
        if (nums == null || nums.length < 4) {
            return new ArrayList<List<Integer>>();
        }
        //创建集合保存返回的数字序列
        ArrayList<List<Integer>> lists = new ArrayList<>();
        //使用hash结构去重
        HashSet<List> set = new HashSet<>();
        //数组元素排序
        Arrays.sort(nums);
        int len = nums.length;
        //双重循环:外层循环从左到右一次遍历 len - 3次
        for (int i = 0; i < len - 3; i++) {
            //内层循环从 i 的右侧一位开始遍历,避免重复
            for (int j = i + 1; j < len - 2; j++) {
                //定义两个指针本别执行j后边元素和最后一个元素
                int left = j + 1, right = len - 1;
                while (true) {
                    //如果四个数的和等于target:使用hash结构去重并添加到集合
                    if (nums[i] + nums[j] + nums[left] + nums[right] == target) {
                        ArrayList<Integer> list = new ArrayList<>();
                        list.add(nums[i]);
                        list.add(nums[j]);
                        list.add(nums[left]);
                        list.add(nums[right]);
                        if (set.add(list)) {
                            lists.add(list);
                        }
                        left++;
                        //否则移动左右指针
                    }
                    //如果四个数的和大于target
                    if (nums[i] + nums[j] + nums[left] + nums[right] > target) {
                        right--;
                    }
                    //如果四个数的和小于target
                    if (nums[i] + nums[j] + nums[left] + nums[right] < target) {
                        left++;
                    }
                    //循环结束条件
                    if (left == right) {
                        break;
                    }
                }
            }
        }
        //返回
        return lists;
    }

以上是关于LeetCode18:四数之和的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 18. 四数之和

leetcode 每日一题 18. 四数之和

LeetCode18:四数之和

leetcode 18. 四数之和

LeetCode:四数之和18

LeetCode#18-四数之和