算法——双指针(day4)

news2024/9/21 4:20:10

15.三数之和

 

15. 三数之和 - 力扣(LeetCode) 

题目解析:

这道题目说是三数之和,其实这和我们之前做过的两数之和是一个规律的~无非就是我们需要实时改动target的值。先排好序,然后固定一个数取其负值作target,然后我们再从除固定数以外的范围内寻找两数之和为target的数,这样再与固定数相加就得到0了,形成三元数组。

 

算法解析:

这就是两数和的核心图解,唯一区别就是我们的target值是随着固定数的变化而发生改变的~

废话不多说,本题的难点就在于去重以及去重时的越界问题。因为按照题目规定类似于

【-1,0,-1】与【-1,-1,0】这种会算重复项只能取其一,而这也是我们优先选择排序的原因,在排行序后二者就变为【-1,-1,0】,更容易去重。

去重分两个阶段,一是【left,right】范围之间的去重,另一个是固定数first遍历数组的去重。

所以我们给出的去重方案就是观察移动前后的数值是否相同,如果相同那就再移动一位,直到不同为止。不过这样也引发了新的问题:越界~

 

我们发现left与right的选取是需要在【left,rigtht】这个界限里面的所以只需要加上一层条件即可(left<right)~

 固定数first同理:

代码: 


class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ret;
        sort(nums.begin(), nums.end());
        int n = nums.size();
        int first = 0;
        while (first <= n - 3)
        {
            //小优化
            if (nums[first] > 0) break;
            int left = first + 1;
            int right = n - 1;
            int target = -nums[first];
            //一轮比较
            while (left < right)
            {
                int sum = nums[left] + nums[right];
                if (sum > target)
                {
                    --right;
                }
                else if (sum < target)
                {
                    ++left;
                }
                else
                {
                    ret.push_back({ nums[first],nums[left],nums[right] });
                    right--;
                    left++;
                    //left与right去重
                    while (left < right && nums[right + 1] == nums[right])
                    {
                        right--;
                    }
                    while (left < right && nums[left - 1] == nums[left])
                    {
                        left++;
                    }
                }

            }
            //固定数去重
            first++;
            while (first < n && nums[first - 1] == nums[first])
            {
                first++;
            }

        }
        return ret;
    }
};

18.四数之和

18. 四数之和 - 力扣(LeetCode)

题目解析:

四数之和别看多了一个数,其实和三数之和还是同一个模板,没有本质区别

算法解析:

 

找四数之和我们可以先拆分成固定数a与三数之和,那么三数之和的值就得为target-a。这样a与三数之和才相加才可以变为target,而在三数之和中就得拆分成固定数b与两数之和,那么两数之和的值就得为target-a-b,这样才能与b相加得到target-a。

所以只要在三数之和的代码中把控好target-a-b的值就行了,除此之外再多加一个对固定数a的去重就好了~

 代码:

在三数之和外套一层固定数a的循环以及去重复,另外改变目标值t变为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();
        int a = 0;
        //固定数a
        while (a <= n - 4)
        {
            //固定数b
            int b = a + 1;
            while (b <= n - 3)
            {
                int left = b + 1;
                int right = n - 1;
                //防止数据溢出强转类型
                long long t = (long long)target - nums[b] - nums[a];
                while (left < right)
                {
                    int sum = nums[left] + nums[right];
                    if (sum > t)
                    {
                        --right;
                    }
                    else if (sum < t)
                    {
                        ++left;
                    }
                    else
                    {
                        ret.push_back({ nums[a],nums[b],nums[left],nums[right] });
                        right--;
                        left++;
                        //一级去重复
                        while (left < right && nums[right + 1] == nums[right])
                        {
                            right--;
                        }
                        while (left < right && nums[left - 1] == nums[left])
                        {
                            left++;
                        }
                    }

                }
                //二级去重
                b++;
                while (b < n && nums[b - 1] == nums[b])
                {
                    b++;
                }

            }
            //三级去重
            a++;
            while (a < n && nums[a - 1] == nums[a])
            {
                a++;
            }

        }
        return ret;
    }
};

 

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

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

相关文章

单链表<数据结构 C版>

目录 概念 链表的单个结点 链表的打印操作 新结点的申请 尾部插入 头部插入 尾部删除 头部删除 查找 在指定位置之前插入数据 在任意位置之后插入数据 测试运行一下&#xff1a; 删除pos结点 删除pos之后结点 销毁链表 概念 单链表是一种在物理存储结构上非连续、非顺序…

Golang | Leetcode Golang题解之第264题丑数II

题目&#xff1a; 题解&#xff1a; func nthUglyNumber(n int) int {dp : make([]int, n1)dp[1] 1p2, p3, p5 : 1, 1, 1for i : 2; i < n; i {x2, x3, x5 : dp[p2]*2, dp[p3]*3, dp[p5]*5dp[i] min(min(x2, x3), x5)if dp[i] x2 {p2}if dp[i] x3 {p3}if dp[i] x5 {p5…

【PostgreSQL教程】PostgreSQL 选择数据库

博主介绍:✌全网粉丝20W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…

图论模型-迪杰斯特拉算法和贝尔曼福特算法★★★★

该博客为个人学习清风建模的学习笔记&#xff0c;部分课程可以在B站&#xff1a;【强烈推荐】清风&#xff1a;数学建模算法、编程和写作培训的视频课程以及Matlab等软件教学_哔哩哔哩_bilibili 目录 ​1图论基础 1.1概念 1.2在线绘图 1.2.1网站 1.2.2MATLAB 1.3无向图的…

基于SpringBoot+Vue的校园疫情防控系统(带1w+文档)

基于SpringBootVue的校园疫情防控系统(带1w文档) 基于SpringBootVue的校园疫情防控系统(带1w文档) 主要对首页、个人中心、学生管理、疫情动态管理、知识信息管理、防疫教育管理、健康打卡管理、请假申请管理、出校登记管理、入校登记管理、核酸报告管理、交流论坛、系统管理的…

MySQL的建表及查询

一。建立表 mysql> create table student(id int(10) not null unique primary key,name varchar(20) not null,sex varchar(4),birth year,department varchar(20),address varchar(50)); mysql> create table score(id int(10) not null unique primary key auto_incr…

精明选择施工项目管理工具的实用建议

国内外主流的10款施工项目进度管理软件对比&#xff1a;PingCode、Worktile、Contractor Foreman、建设工程项目管理平台&#xff08;JSGC&#xff09;、智慧工地综合管理系统、工程项目信息管理系统&#xff08;GCXX&#xff09;、Buildertrend、Procore、Autodesk Constructi…

Edge侧边栏copilot消失

Edge侧边栏copilot消失 当前环境 自己ip问题已解决&#xff0c;edge中已登录账号&#xff0c;地区已设置为美国&#xff0c;语言已设置为英文。具体可以通过空白页右上角的setting验证 解决方案 首先&#xff0c;打开“任务管理器”&#xff0c;在其中找到 Microsoft Edge…

【C语言】动态内存管理(下)(realloc函数)

文章目录 前言1. realloc2. realloc函数在调整空间时的细节2.1 针对情况1&#xff08;realloc后面有足够的内存空间&#xff09;2.2 针对情况2&#xff08;realloc后面没有足够的内存空间&#xff09;2.3 realloc函数使用的注意事项2.4 realloc的使用实例2.5 realloc函数的补充…

ubuntu安装mysql8.0

文章目录 ubuntu版本安装修改密码取消root跳过密码验证 ubuntu版本 22.04 安装 更新软件包列表 sudo apt update安装 MySQL 8.0 服务器 sudo apt install mysql-server在安装过程中&#xff0c;系统可能会提示您设置 root 用户的密码&#xff0c;请务必牢记您设置的密码。…

产线中有MES系统 还有安装SCADA的必要吗?

MES系统即制造执行系统&#xff08;Manufacturing Execution System&#xff09;&#xff0c;是一种面向车间层的管理信息系统&#xff0c;旨在通过信息传递优化从订单下达到产品完成的全过程管理。 MES可以为企业提供包括制造数据管理、计划排程管理、生产调度管理、库存管理、…

网路布线和数值转换

文章目录 信号的分类数字信息的优势双绞线分类双绞线标准与分类 光纤的特点光纤分为单模光纤和多模光纤 光纤接口双绞线的连接规范EIA/TIA-568A和568B 线缆的连接综合布线系统无线电波的传输方式 数制转换十进制转二进制计算机的数值 信号的分类 1.模拟信号 2.数字信号 数字信…

动态住宅IP和静态住宅IP使用上有差异吗?

在互联网连接的世界中&#xff0c;IP地址是我们识别和访问网络资源的关键。住宅IP地址&#xff0c;特别是动态住宅IP和静态住宅IP&#xff0c;是两种不同类型的IP分配方式&#xff0c;它们在使用和功能上存在显著差异。 1. IP地址的稳定性 动态住宅IP&#xff1a;这种IP地址是…

七月份信息课总结

总结 七月份信息课总结算法记录线性代数&#xff1a;数论&#xff08;这是信竞生和数竞生都最难跨出的一步&#xff09;&#xff1a;动态规划&#xff08;~~DP万岁&#xff01;&#xff01;&#xff01;~~&#xff09;组合数学&#xff08;恶心&#xff0c;但我很喜欢&#xff…

Python爬虫-淘宝搜索热词数据

前言 本文是该专栏的第70篇,后面会持续分享python爬虫干货知识,记得关注。 在本专栏之前,笔者有详细针对“亚马逊Amazon搜索热词”数据采集的详细介绍,对此感兴趣的同学,可以往前翻阅《Python爬虫-某跨境电商(AM)搜索热词》进行查看。 而在本文,笔者将以淘宝为例,获取…

Linux----Mplayer音视频库的移植

想要播放视频音乐就得移植相关库到板子上 Mplayer移植需要依赖以下源文件&#xff1a;(从官网获取或者网上) 1、zlib-1.2.3.tar.gz &#xff1a;通用的内存空间的压缩库。 2、libpng-1.2.57.tar.gz :png格式图片的压缩或解压库 3、Jpegsrc.v9b.tar.gz : jpeg格式图片的压…

linux配置podman阿里云容器镜像加速器

1.下载podman yum install -y podman systemctl status podman systemctl start podman 2.获取阿里云个人容器镜像加速器地址 访问阿里云官网&#xff1a;首先&#xff0c;您需要访问阿里云&#xff08;Alibaba Cloud&#xff09;的官方网站。阿里云官网的URL是&#xff1a;…

医疗器械维修人员培训的重要性及其操作策略

医疗器械维修人员培训的重要性及其操作策略是确保医疗器械持续、安全、有效运行的关键。以下是对其重要性的解释以及相应的操作策略&#xff1a; 医疗器械维修人员培训的重要性 确保患者安全 经过培训的维修人员能够更准确地诊断问题&#xff0c;及时修复设备&#xff0c;避…

【IntelliJ IDEA】一篇文章集合所有IDEA的所有设置

IntelliJ IDEA 是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;其设置涵盖了多个方面&#xff0c;以满足不同开发者的需求和偏好。由于 IDEA 的设置相当复杂和详尽&#xff0c;这里无法在一篇简短的文章中详细介绍所有设置。然而&#xff0c;我可以提供一…

轻松掌握:两个方法合并ZIP分卷压缩包

在文件传输和存储过程中&#xff0c;为了绕过文件大小限制或优化下载速度&#xff0c;我们常常会将大型文件分割成多个较小的ZIP分卷压缩包。然而&#xff0c;在接收这些分卷后&#xff0c;如何正确地将它们合并回原始的ZIP文件&#xff0c;可能是许多用户面临的一个问题。本文…