[哈希表]四数之和

104 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述

原文链接:18. 四数之和
具体描述: 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • a、b、c 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

示例 1:

输入:nums = [1,0,-1,0,-2,2], target = 0 输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

示例 2:

输入:nums = [2,2,2,2,2], target = 8 输出:[[2,2,2,2]]

提示:

  • 1 <= nums.length <= 200
  • -10^9 <= nums[i] <= 10^9
  • -10^9 <= target <= 10^9

二、思路分析

这道题目和三数之和(可以点开链接看看怎么回事,再来做这个!)可以说是一模一样,四数之和就是一个数加三个数字嘛!在套一层for循环,然后target减去这层for循环的值不就变成三数之和啦嘛!

我提交啦好几次,才AC!所以需要注意一下这几点

  • 因为目标值可以是负数,所以排序之后第一个数如果大于目标值,如果后面是负数也是可以有结束的,所以可以变成这样:if (nums[j] > target && nums[j] > 0) return result;
  • 写三数之和的时候,如果大于tmp(int tmp = target - nums[j];)可以是break,跳出当前循环,而不是return!if (nums[i] > tmp && nums[i] > 0) break;

三、AC代码

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);

        for (int j = 0; j < nums.length - 1; j ++){
            if (nums[j] > target && nums[j] > 0) return result;

            if (j > 0 && nums[j - 1] == nums[j]) continue;

            int tmp = target - nums[j];
            
            for (int i = j + 1; i < nums.length; i ++){
                
                if (nums[i] > tmp && nums[i] > 0) break;

                if (i > (j + 1) && nums[i - 1] == nums[i]) continue;

                int left = i + 1;
                int right = nums.length - 1;
                while (right > left){
                    int sum = nums[i] + nums[left] + nums[right];
                    if (sum > tmp){
                        right--;
                    }else if(sum < tmp){
                        left++;
                    }else{
                        result.add(Arrays.asList(nums[j], nums[i], nums[left], nums[right]));
                        while (right > left && nums[right - 1] == nums[right]) right--;
                        while (right > left && nums[left + 1] == nums[left]) left++;

                        right--;
                        left++;
                    }
                }
            }
        }

        return result;
    }
}

四、总结

  • 三数之和和四数之和非常类似,但是要注意细节!

感谢大家的阅读,我是Alson_Code,一个喜欢把简单问题复杂化,把复杂问题简单化的程序猿! ❤