力扣:18.四数之和

一、做题链接:18. 四数之和 - 力扣(LeetCode)

二、题目分析

1.做这一道题之前本博主建议先看上一篇《三数之和》

2.题目分析

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

  • 0 <= a, b, c, d < n
  • abcd 互不相同
  • 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]]

由题可知:做这个题要主要面临的困难是去重和漏选,去重主要利用的是排序,set等,漏选就枚举

示例解析[1,0,-1,0,-2,2]->排序后[-2,-1,0,0,1,2]

以此类推得出最终答案

三、算法分析

1.暴力枚举法:排序+四层for循环+set去重;时间复杂度O(n^4)-----》这个不可跑过力扣

2.双指针+单调性+两层for循环;时间复杂度O(n^3)-》利用率三数之和--》利用率两数之和

算法步骤:

1.排序

2.设置第一个固定数

3.设置第二个固定数

4.两数之和,设置两个指针left,right-》降低复杂度的关键

5.细节处理,重点关注去重问题

注意事项:

去重:1.去除第一固定数的重如:0,0,求出来的一样

2.去除第二个数的重如:第一固定数是-1,第二固定数:0,0结果一样

3.去除两数之和的重

四、代码编写

java 复制代码
 public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);//排序
        List<List<Integer>> Foursum = new ArrayList<>();
        for (int i = 0; i < nums.length; )//固定一个数
        {
            for (int j = i + 1; j < nums.length;)//固定第二个数
            {

                long tar = (long) target - nums[i] - nums[j];//求出两数之和的目标
                List<Integer> list = new ArrayList<>();
                //两数之和
                int left = j + 1;
                int right = nums.length - 1;
                while (left < right) {
                    if (left < nums.length && nums[left] + nums[right] < tar) {
                        left++;
                    } else if (right > 0 && nums[left] + nums[right] > tar) {
                        right--;
                    } else {
                        list.add(nums[i]);
                        list.add(nums[j]);
                        list.add(nums[left]);
                        list.add(nums[right]);
                        Foursum.add(list);
                        //去除第三重
                        while (left < nums.length && nums[left] == list.get(2)) {
                            left++;
                        }
                        while (right > 0 && nums[right] == list.get(3)) {
                            right--;
                        }
                    }
                }
                //去除第二重
                j++;
                while (j < nums.length && nums[j] == nums[j - 1]) {
                    j++;
                }
            }
            //去除第三重
            i++;
            while (i<nums.length && nums[i]==nums[i-1])
            {
                i++;
            }
        }
        return Foursum;
    }

你学废了吗

相关推荐
AI软著研究员7 小时前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish7 小时前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
颜酱8 小时前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
地平线开发者1 天前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶
董董灿是个攻城狮1 天前
大模型连载2:初步认识 tokenizer 的过程
算法
地平线开发者1 天前
地平线 VP 接口工程实践(一):hbVPRoiResize 接口功能、使用约束与典型问题总结
算法·自动驾驶
罗西的思考1 天前
AI Agent框架探秘:拆解 OpenHands(10)--- Runtime
人工智能·算法·机器学习
HXhlx1 天前
CART决策树基本原理
算法·机器学习
Wect1 天前
LeetCode 210. 课程表 II 题解:Kahn算法+DFS 双解法精讲
前端·算法·typescript
颜酱1 天前
单调队列:滑动窗口极值问题的最优解(通用模板版)
javascript·后端·算法