(双指针) 有效三角形的个数 和为s的两个数字 三数之和 四数之和

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

文章目录

前言

一、有效三角形的个数(medium)

1.1、题目

1.2、讲解算法原理

1.3、编写代码

二、和为s的两个数字

2.1、题目

2.2、讲解算法原理

2.3、编写代码

三、三数之和

3.1、题目

3.2、讲解算法原理

3.3、编写代码

四、四数之和

4.1、题目

4.2、讲解算法原理

4.3、编写代码

总结



前言

世上有两种耀眼的光芒,一种是正在升起的太阳,一种是正在努力学习编程的你!一个爱学编程的人。各位看官,我衷心的希望这篇博客能对你们有所帮助,同时也希望各位看官能对我的文章给与点评,希望我们能够携手共同促进进步,在编程的道路上越走越远!


提示:以下是本篇文章正文内容,下面案例可供参考

一、有效三角形的个数(medium)

1.1、题目

1.2、讲解算法原理

补充数学知识:给我们三个数,判断是都能够构成三角形。

步骤:利用单调性,使用双指针算法来解决问题。

  1. 先固定最大的数;
  2. 在最大的数的左区间内,使用双指针算法,快速统计出符合要求的三元组的个数。

来举例一个区间[2,2,3,4,4,9,10]来说明一下情况:

  • 优化:先对整个数组排序,用于固定最大的数。
  • 我们根据三角形的满足条件得出的两个结论:因为数组是升序的,所以设a和b为最小的两边,c为最大的边,a + b > c就能构成三角形;a + b <= c便不能构成三角形。
  • 我们使用双指针的思想,假设数组的下标为指针,设left指针指向数组下标为0的位置,设right指针指向数组中最大的数的左区间中的最大值。
  1. 拿上面的数组为例,先固定最大的数为10,设left为第一个2所在的位置,right为9所在的位置,left + right大于10,因为是升序,所以当right不变,left指向2~9之间的任意数时,都符合三角形的条件,因此得出的结论:下标right - left的值为满足三角形的情况,9所在的位置可以划掉,right--。
  2. 此时left为第一个2,right为5,最大值依旧为10:2 + 5 < 10,不构成三角形的条件,left++,再次判断三角形的条件,重复操作,直到left和right相遇,最大值为10所在的情况查看完毕,更新最大值。

1.3、编写代码

class Solution 
{
public:
    int triangleNumber(vector<int>& nums) 
    {
        // 先进行排序
        sort(nums.begin(), nums.end());

        // 利用双指针解决问题
        int ret = 0, n = nums.size();
        for(int i = n-1; i>= 2; i--)// 固定最大值
        {
            int left = 0,right = i - 1;
            while(left < right)
            {
                if(nums[left] + nums[right] > nums[i])
                {
                    ret += (right - left);
                    right--;
                }
                else
                {
                    left++;
                }
            }
        }
        return ret;
    }
};

二、和为s的两个数字

2.1、题目

2.2、讲解算法原理

利用单调性,使用双指针算法解决问题。

举一个数组[2,7,11,15,19,21],t = 30为例:设left指针指向2,right指针指向21,让两数相加来和t值(30)比较。

分为三种情况:

  1. sum < t:left为2,right为21,相加得23 < t(30),因为数组为递增顺序,left和right区间的数字都比21要小,因此划掉2,left++;
  2. sum > t:left为11,right为21,相加得32 > t(30),left和right区间的数值都比left(11)要大,因此划掉21,right--;
  3. sum = t(30):返回结果。

2.3、编写代码

class Solution 
{
public:
    vector<int> twoSum(vector<int>& price, int target) 
    {
        int left = 0,right = price.size() - 1;
        while(left < right)
        {
            if(price[left] + price[right] > target)
            {
                right--;
            }
            else if(price[left] + price[right] < target)
            {
                left++;
            }
            else
            {
                return {price[left],price[right]};
            }
        }
        // 照顾编译器
        return {-1,-1};
    }
};

三、三数之和

3.1、题目

3.2、讲解算法原理

步骤:

  1. 排序;
  2. 固定一个数a;(小优化:对于下面的数组来说,a > 0之后,不管left 和 right 两个指针指向哪里,和 a 相加之后,都不会等于0,因此 a > 0之后,就可以结束了)
  3. 在该固定的数a后面的区间内,利用“双指针算法”快速找到两个的和等于 -a 即可。

处理细节问题:

1、去重;

  • 找到一种结果之后,left 和 right 指针要跳过重复元素;
  • 当使用完一次双指针算法之后,i 也需要跳过重复的元素;
  • 避免越界。

2、不漏;

  • 找到一种结果之后,不要“停”,缩小区间,继续寻找。

3.3、编写代码

class Solution 
{
public:
    vector<vector<int>> threeSum(vector<int>& nums) 
    {
        vector<vector<int>> ret;// 定义一个二级数组用于储存数组

        // 排序
        sort(nums.begin(), nums.end());
        int i = 0, n = nums.size();
        // 固定一个数a
        for(i = 0; i < n; ) // for()循环中初始化、判断和调整这三个部分都可以写为空
        {
            // 小优化
            if(nums[i] > 0) break;
            int left = i + 1, right = n - 1, target = -nums[i];// target两个指针所指向的数相加==固定数的负数
            while(left < right)
            {
                int sum = nums[left] + nums[right];
                if(sum > target) right--;
                else if(sum < target) left++;
                else 
                {
                    ret.push_back({nums[i], nums[left], nums[right]});
                    left++, right--;
                    // 去重操作 left right
                    while(left < right && nums[left] == nums[left - 1]) left++;
                    while(left < right && nums[right] == nums[right + 1]) right--;
                }
            }
            i++;
            // 去重操作 i
            while(i < n && nums[i] == nums[i - 1]) i++;
        }
        return ret;
    }
};

四、四数之和

4.1、题目

4.2、讲解算法原理

排序 + 双指针:

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

三数之和:

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

处理细节问题:

1、去重;

  • 找到一种结果之后,left 和 right 指针要跳过重复元素;
  • 当使用完一次双指针算法之后,i 也需要跳过重复的元素;
  • 避免越界。

2、不漏;

  • 找到一种结果之后,不要“停”,缩小区间,继续寻找。

4.3、编写代码

class Solution 
{
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) 
    {
        // 定义一个二级数组,用来存放数组
        vector<vector<int>> ret;

        // 排序
        sort(nums.begin(),nums.end());

        // 固定一个数a
        int i = 0,n = nums.size();
        for(i = 0; i < n; )
        {
            // 固定数b ---> 将四数求和转换成三数求和
            for(int j = i + 1; j < n; )
            {
                // 利用双指针的算法
                int left = j + 1, right = n -1; 
                while(left < right)
                {
                    // 这个地方用int类型,有可能会超出int的范围,用long long
                    long long aim = (long long)target - nums[i] - nums[j];
                    int sum = nums[left] + nums[right];
                    if(sum > aim) right--;
                    else if(sum < aim) left++;
                    else
                    {
                        ret.push_back({nums[i], nums[j], nums[left], nums[right]});
                        left++, right--;
                        // 去重操作 left right
                        while(left < right && nums[left] == nums[left-1]) left++;
                        while(left < right && nums[right] == nums[right+1]) right--;
                    }
                }
                j++;
                // 去重操作 j
                while(j < n && nums[j] == nums[j-1]) j++;
            }
            i++;
            // 去重操作 i
            while(i < n && nums[i] == nums[i-1]) i++;
        }
        return ret;
    }
};


总结

好了,本篇博客到这里就结束了,如果有更好的观点,请及时留言,我会认真观看并学习。
不积硅步,无以至千里;不积小流,无以成江海。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

动手开发基于Springboot的基础开发框架-01

本系列专题虽然是按教学的深度来定稿的&#xff0c;但在项目结构和代码组织方面是按生产系统的要求来书定的。在本章中主要介绍下基础开发框架的内容。后续所有章节的项目全是在本基础框架的基础上演进的。 工程结构介绍 SpringbootSeries&#xff1a;父工程&#xff0c;定义一…

【信息熵理论-01】最大熵的分布

文章目录 一、说明二、如何认识所谓的“熵”三、熵最大化问题3.1 设置最大化3.2 利用变分微积分 四、更广泛的影响和见解 一、说明 我觉得用最大熵来获取概率分布的方法很给力。您采用一些已知或约束&#xff0c;然后在这些条件下最大化信息熵&#xff0c;瞧&#xff01;你有一…

前端基础学习html(2)

目录 表格标签&#xff1a; 列表标签&#xff1a; 表格标签&#xff1a; <!-- 表格基本架构 --><!-- tr表示一行&#xff0c;td表示一行内单元格 --><!--th为第一行表头加粗居中显示 --><table border"1"><thead><tr><th&g…

【Linux】17. 进程间通信 --- 管道

1. 什么是进程间通信(进程间通信的目的) 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享同样的资源。 通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它&#xff08;它们&#xff09;发生了…

sqlmodel实现唯一性校验3,检查多列同时重复

之前的方案虽然能够解决重复性问题&#xff0c;但是没有覆盖到多列同时重复的情况。 比如&#xff0c;我们可以认为用户名是可以重复的。但是用户名和年龄不能同时重复&#xff0c;那么这种情况该怎么解决呢&#xff1f; 之前的代码如下&#xff1a; from sqlalchemy import…

python直接发布到网站wordpress之三批量发布图片

在前面的文章中&#xff0c;实现了使用python操作wordpress发布文字内容和图片内容。 python直接发布到网站wordpress之一只发布文字-CSDN博客 python直接发布到网站wordpress之二发布图片-CSDN博客 不过&#xff0c;此时发布图片的数量只能是一张图片。但在实际应用中&…

效率跨越式提升的工农业对机器人专业的需求

需求 需要用人的地方一定会逐步收缩。 原来需要人的地方也会逐步被机器人取代。 机器人这个专业最强的悖论就是可以部分取代人。 此处&#xff1a;用人的地方是指“工农业”&#xff0c;包括工业和农业。 机器人工程行业算制造业吗 机器人工程终身学习和工作计划 趋势 工匠…

1077 互评成绩计算

solution 总成绩 &#xff08;老师成绩 同学去掉最高分去掉最低分的平均分&#xff09;/2&#xff0c;其中总成绩四舍五入取整 #include<iostream> #include<algorithm> using namespace std; int main(){int n, m, worst, better, sum, g, x, cnt;scanf("…

【数学建模】天然肠衣搭配问题

2011高教社杯全国大学生数学建模竞赛D题 天然肠衣&#xff08;以下简称肠衣&#xff09;制作加工是我国的一个传统产业&#xff0c;出口量占世界首位。肠衣经过清洗整理后被分割成长度不等的小段&#xff08;原料&#xff09;&#xff0c;进入组装工序。传统的生产方式依靠人工…

每日OJ题_DFS解决FloodFill⑤_力扣417. 太平洋大西洋水流问题

目录 力扣417. 太平洋大西洋水流问题 解析代码 力扣417. 太平洋大西洋水流问题 417. 太平洋大西洋水流问题 难度 中等 有一个 m n 的矩形岛屿&#xff0c;与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界&#xff0c;而 “大西洋” 处于大陆的右边界和下…

自动控制原理MATLAB:控制系统模型构建

在MATLAB中&#xff0c;常用的系统建模方法有传递函数模型、零极点模型以及状态空间模型等。 1系统传递函数模型描述&#xff1a; 命令格式&#xff1a; systf(num,den,Ts); 其中&#xff0c;num、den为分子多项式降幂排列的系数向量,Ts表示采样时间&#xff0c;缺省时描述…

AI 数据观 | TapData Cloud + MongoDB Atlas:大模型与 RAG 技术有机结合,落地实时工单处理智能化解决方案

本篇为「AI 数据观」系列文章第二弹&#xff0c;在这里&#xff0c;我们将进一步探讨 AI 行业的数据价值。以 RAG 的智能工单应用场景为例&#xff0c;共同探索如何使用 Tapdata Cloud MongoDB Atlas 实现具备实时更新能力的向量数据库&#xff0c;为企业工单处理的智能化和自…

在小黑框如何用Python写出多行代码

平时使用python自带的小黑框编译器只能一行代码一行代码的写&#xff0c; 方法一 可以新建一个文本txt格式&#xff0c;然后打开在里面输入你想要的Python代码&#xff0c;然后把名字改成xxx.py&#xff0c;然后点击小黑框&#xff0c;输入 python 把Py文件拖过来回车就行 方…

Hive内部表、外部表

Hive内部表、外部表 1. 内部表&#xff08;Managed Table&#xff09;&#xff1a; 内部表是由Hive完全管理的表&#xff0c;包括数据和元数据。当你删除内部表时&#xff0c;Hive会同时删除表的数据和元数据。内部表的数据存储在Hive指定的默认位置&#xff08;通常是HDFS上…

VBA 创建透视表,录制宏,自动化报表

目录 一. 数据准备二. 需求三. 准备好报表模板四. 执行统计操作&#xff0c;录制宏4.1 根据数据源创建透视表4.2 填充数据到报表4.3 结束宏录制 五. 执行录制好的宏&#xff0c;自动化报表 一. 数据准备 ⏹数据源1 姓名学科成绩丁志敏语文91李平平语文81王刚语文64张伊语文50…

【前端】HTML基础(1)

文章目录 前言一、什么是前端二、HTML基础1、 HTML结构1.1 什么是HTML页面1.2 认识HTML标签1.3 HTML文件基本结构1.3 标签层次结构1.4 创建html文件1.5 快速生成代码框架 三、Emmet快捷键 前言 这篇博客仅仅是对HTML的基本结构进行了一些说明&#xff0c;关于HTML的更多讲解以及…

新能源电燃灶:为人类社会贡献高品质的健康生活

华火新能源电燃灶&#xff0c;作为一种创新的厨房设备&#xff0c;近年来逐渐走进了千家万户&#xff0c;成为了现代家庭厨房的新宠。它不仅改变了传统的烹饪方式&#xff0c;更在环保、节能、安全等方面为人类带来了诸多贡献。本文将从多个方面探讨华火新能源电燃灶对人类的贡…

知行之桥EDI系统跨平台版本安装报错及解决方案

本文将为大家介绍如何在Windows系统中安装知行之桥EDI系统跨平台版本的常见报错以及解决方案。如下图所示&#xff1a; 在知行软件官网的导航栏中点击 下载 按钮&#xff0c;即可看到知行之桥EDI系统不同版本的下载选项&#xff0c;点击右侧跨平台版本&#xff0c;选择 Windows…

移动硬盘无法被识别怎么办?恢复移动硬盘3个正确做法

移动硬盘已成为我们日常生活和工作中不可或缺的数据存储设备。然而当移动硬盘突然无法被电脑识别时&#xff0c;往往会让人倍感焦虑。面对这种情况我们不必过于慌张&#xff0c;下面一起来看看指南解决。 解决方法一&#xff1a;检查硬件连接与供电 检查接口连接&#xff1a…

uniapp离线在Xcode上打包后提交审核时提示NSUserTrackingUsageDescription的解决方法

uniapp离线在Xcode上打包后提交审核时提示NSUserTrackingUsageDescription的解决方法 问题截图&#xff1a; 亲测有效的方法 方法一&#xff1a; 选择通过uniapp的开发工具Hbuilder来进行在线打包&#xff0c;取消默认勾选的以下选项。 然后进行在线打包就不会存在提交审…