双指针(8)_单调性_四数之和

news2024/11/25 12:47:44

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

双指针(8)_单调性_四数之和

收录于专栏【经典算法练习
本专栏旨在分享学习C++的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 题目链接:

2.题目描述 :

3.解法 :

    解法一(暴力枚举) :

    算法思路 :

    代码展示 :

    结果分析 :

    解法二(排序 + 双指针) :

    算法思路 :

    图解流程 :

    代码展示 :

    结果分析 :

4.总结 :


温馨提示: 大家没看三数之和这道题可以先去了解一下,思路基本一样

双指针(7)_单调性_三数之和-CSDN博客

1. 题目链接:

OJ链接-----. - 力扣(LeetCode)

2.题目描述 :

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

  • 0 <= a, b, c, d < n
  • abc 和 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
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109

3.解法 :

    解法一(暴力枚举) :

    算法思路 :

这里的暴力枚举非常朴实无华,就是排序 + 四层循环 + set去重

这里简单分析一下时间复杂度:

这个暴力枚举时间复杂度为O(N^4),题目数组的数据范围是在200之内,所以暴力枚举数据级别可达1.6*10^9,绝对是过不了这道题的

算法题的数据范围就是这样,你的暴力算法永远只差一点,而要去达到这一点需要去更改其他算法去简化我们的暴力算法.

    代码展示 :

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        set<vector<int>> T;
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for(int i = 0; i < n; i++)
            for(int j = i + 1; j < n; j++)
                for(int k = j + 1; k < n; k++)
                    for(int l = k + 1; l < n; l++)
                    {
                        long long sum = (long long)nums[i] + nums[j] + nums[k] + nums[l];
                        if(sum == target) T.insert({nums[i], nums[j], nums[k], nums[l]});
                    }

        vector<vector<int>> ret(T.begin(), T.end());
        return ret;
    }
};

 

    结果分析 :

在我们意料之中,暴力算法只差6个例子就能顺利通过!!!

但是这次暴力算法对我们还是有收获的,在我们遇到第283个例子时,我们发现,数据溢出的问题,这是我们开始没有想到的,因为例子中这四个数相加会超出int的范围(爆int),所以后面我就使用long long进行存贮,这为后面我们的优化算法进行了提醒

这次的爆int其实并不是空穴来风的,我们之前看算法题时,只会看它的数组数据范围,没有看过数组中数据的范围,在这道题目中,每个数是在10^9范围之内,而我们的int的数据范围为[-2147483648, 2147483647]之间,也就是大概2*10^9,我们这里四个数相加肯定是爆了int,这也是算法题惯用的伎俩.

    解法二(排序 + 双指针) :

强烈推荐大家先去看一下三数之和这道题,思路基本一样

双指针(7)_单调性_三数之和-CSDN博客

    算法思路 :

a. 依次固定一个数a;

b. 在这个数a的后面区间上,利用[三数之和]找到三个数,使这三个数的和等于target - a即可.

    图解流程 :

详细的细节问题已经在三数之和中讲解过,这里就不再多说:

总结:

  1. 依次固定一个数a;
  2. 在a后面的区间内,利用"三数之和"找到三个数使这三个数的和等于target - a即可
    1. 依次固定一个数b;
    2. 在b后面的区间内,利用双指针找到两个数,

使这两个数的和等于target - a -b即可.

    代码展示 :

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> ret;
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for(int i = 0; i < n; )
        {
            for(int j = i + 1; j < n; )
            {
                int left = j + 1, right = n - 1;
                long long sum = (long long)target - nums[i] - nums[j];
                while(left < right)
                {
                    if(nums[left] + nums[right] > sum) right--;
                    else if(nums[left] + nums[right] < sum) left++;
                    else
                    {
                        ret.push_back({nums[i], nums[j], nums[left++], nums[right--]});
                        while(left < right && nums[left] == nums[left - 1]) left++; 
                        while(left < right && nums[right] == nums[right + 1]) right--; 
                    }
                } 
                j++;
                while(j < n && nums[j] == nums[j - 1]) j++;
            }
            i++;
            while(i < n && nums[i] == nums[i - 1]) i++;
        }
        return ret;
    }
};

 

    结果分析 :

顺利通过!!!

时间复杂度分析:

外层两层for循环,内层一层while循环,总的时间复杂度为O(N^3)

空间复杂度分析:
排序的sort出战压栈会占用空间(底层用的是快排)O(logN),其他设置的常量可以忽略不记,总的时间复杂度还是O(logN)

4.总结 :

无论是两数之和,三数之和或者是四数之和它们的共同思想都是一样的,都是先经过排序,使得数组中的数有序,在利用数组中的单调性使用双指针算法进行求解. 

好了,双指针系类完结撒花,下面一个专题是滑动窗口问题,感兴趣的宝子们赶紧点赞关注收藏起来吧!

欢迎 点赞👍 收藏✨ 留言✉ 加关注💓

大家也可以关注我的算法专栏[经典算法练习]

我们明天见!!!

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2123638.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QDY421F-16P-25液氨不锈钢液动紧急切断阀

一、产品概述 QDY421F-16P-25液氨不锈钢液动紧急切断阀&#xff0c;采用先进的液动驱动技术&#xff0c;结合高质量的不锈钢材质&#xff0c;专为满足液氨等腐蚀性介质的紧急切断需求而设计。该阀门的工作压力可达16MPa&#xff0c;适用于DN25&#xff08;即25毫米&#xff09;…

单向链表概述

文章目录 &#x1f34a;自我介绍&#x1f34a;单向链表概述数据域和指针域数据类型设计 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff09;哦~ &#x1f34a;自我介绍 Hello,大家好&#xff0c;我是小珑也要…

高斯消元法

顾名思义就是我们初中所知的消元方程&#xff0c;用来解方程的&#xff0c;但是如果自己手动去实现的话&#xff0c;还是有一部分难度的&#xff0c;因此我们也会用到线代这门科目&#xff0c;因为这是实现计算自动化的关键步骤 现在这里放上高斯消元的板子&#xff08;可以用…

正点原子阿尔法ARM开发板-IMX6ULL(四)——汇编LED驱动实验-下

文章目录 一、驱动编写1.1 配置GPIO的电气属性1.2 配置GPIO的功能&#xff08;GDIR寄存器&#xff09;1.3 设置输出&#xff08;DR寄存器&#xff09;1.4 最终代码 二、编译程序2.1 编译程序2.2 链接文件2.3 格式转换成BIN文件2.4 反汇编 三、烧写bin到SD卡中并运行3.1 准备工作…

中介者模式mediator

学习笔记&#xff0c;原文链接 https://refactoringguru.cn/design-patterns/mediator 减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互&#xff0c; 迫使它们通过一个中介者对象进行合作。

数据结构:树与二叉树(2)

1、线索二叉树 1.1线索二叉树的定义 &#xff08;1&#xff09;线索二叉树有啥用&#xff1f; 普通二叉树的节点包含左孩子和右孩子的信息&#xff0c;但并没有直接存储关于“直接前驱”和“直接后继”的信息&#xff0c;结点的前驱和后继只能在遍历过程中获得。 因此这里引…

Springboot中mybatis的使用

一.创建Springboot项目并加载依赖 1.利用IDEA创建SpringBoot项目&#xff0c;并勾选必须依赖&#xff0c;步骤如下&#xff08;IDEA版本为2024版&#xff09; 注意&#xff1a; 1.首先更换镜像源&#xff0c;否则加载配置环境比较慢&#xff0c;网上搜阿里的镜像源就行。 2…

关于在vue2中使用el-tree的记录

此文章会持续更新在使用el-tree过程中应用到的功能... 先看此效果&#xff1a; html&#xff1a; <el-tree :data"data" :props"defaultProps" node-click"handleNodeClick">//自定义节点内容<span slot-scope"{ data }"&g…

Leetcode面试经典150题-135.分发糖果

解法都在代码里&#xff0c;不懂就留言或者私信 阿里字节都考过 class Solution {/**对于每个孩子来说&#xff0c;我们试一下从左边开始它应该分几个糖果&#xff0c;然后看一下从右边开始它应该分几个糖果然后左右取最大值&#xff0c;每个位置求和就是我们要的答案 */publ…

【解决keil不能跳转函数声明的问题】

第一步&#xff1a;将魔术棒中的output选项里Browase Information功能打开 第二步&#xff1a;重新编译整个工程 第三步&#xff1a;跳转测试

Java项目: 基于SpringBoot+mybatis+maven实现的IT技术交流和分享平台(含源码+数据库+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven实现的IT技术交流和分享平台 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美…

【笔记】2.1 石英类原料

2.1.1 石英类原料的种类 石英&#xff1a;结晶矿物。 &#xff08;1&#xff09;石英砂&#xff08;硅砂&#xff09; 石英石、长石在水、二氧化碳、温度作用下风化分解由水流冲击沉积而形成。 主要成分为&#xff0c;质地纯净的硅砂为白色&#xff0c;其中若含有少量杂质&…

SpringCloud集成MybatisPlus,实现MySQL多数据源配置

引入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.0</version> </dependency><dependency><groupId>com.alibaba</groupId><art…

Apache DataFusion查询引擎简介

01 简介 DataFusion是一个查询引擎&#xff0c;其本身不具备存储数据的能力。正因为不依赖底层存储的格式&#xff0c;使其成为了一个灵活可扩展的查询引擎。它原生支持了查询CSV&#xff0c;Parquet&#xff0c;Avro&#xff0c;Json等存储格式&#xff0c;也支持了本地&#…

TCP通信实现

前言 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于流的通信协议。它是互联网协议栈&#xff08;TCP/IP&#xff09;中的核心协议之一&#xff0c;主要用于保证在计算机网络中可靠地传输数据。 TCP通信的基…

面向物联网基础的智能农业环境的节能边缘-雾-云计算架构

这篇论文的标题是《Energy-Efficient Edge-Fog-Cloud Architecture for IoT-Based Smart Agriculture Environment》&#xff0c;作者是Hatem A. Alharbi和Mohammad Aldossary&#xff0c;发表在IEEE Access期刊上。论文的主要内容可以概括为以下几个部分&#xff1a; 摘要&am…

【JVM 工具命令】JAVA程序线上问题诊断,JVM工具命令的使用,jstat, jstack,jmap命令的使用

【JVM 工具命令】JAVA程序线上问题诊断&#xff0c;JVM工具命令的使用&#xff0c;jstat&#xff0c; jstack&#xff0c;jmap命令的使用 1. JVM监控工具&#xff1a; Jstat命令 通过这个命令查询java程序&#xff0c;gc的情况 jstat -gcutil {pid} 5000 12 5000 表示5000…

JavaWeb【day12】--(SpringBootWeb登录认证)

案例-登录认证 在前面的课程中&#xff0c;我们已经实现了部门管理、员工管理的基本功能&#xff0c;但是大家会发现&#xff0c;我们并没有登录&#xff0c;就直接访问到了Tlias智能学习辅助系统的后台。 这是不安全的&#xff0c;所以我们今天的主题就是登录认证。 最终我们…

Mysql高级篇(中)—— 索引优化

Mysql高级篇&#xff08;中&#xff09;—— 索引优化 一、索引分析案例案例 1&#xff1a;单表查询案例 2&#xff1a;两表连接查询案例 3&#xff1a;三表连接查询 二、避免索引失效常见索引失效场景简述场景 1场景 2场景 3场景 4场景 5场景 6 三、索引优化文字版示例版 一、…

每日OJ_牛客_数组中出现次数超过一半的数字

目录 牛客_数组中出现次数超过一半的数字 解析代码1 解析代码2 牛客_数组中出现次数超过一半的数字 数组中出现次数超过一半的数字__牛客网 给一个长度为 n 的数组&#xff0c;数组中有一个数字出现的次数超过数组长度的一半&#xff0c;请找出这个数字。例如输入一个长度为…