2024年10月30日(双指针算法)

一.和为s的两个数字:

1.题目描述:

这个题目就是找出两个数,这两个数的和是目标值,找到其中一对就可以返回了。

2.算法原理:

        方法一:

              暴力枚举的策略:

        就是两层for循环,固定一个数,然后另一个数去遍历整个数组,去加加然后找出是否有值加

起来两数之和是目标值的。

     伪代码:

for(i=0;i<n;i++){
  for(j=i+1;j<n;j++){
     check(nums[i]+nums[j]==t);
 }
}

这个暴力枚举的方法的时间复杂度就是O(n^2).所以去编写代码这个时间复杂度肯定是过不了的。

    方法二:

      任何题目第一个想到的方法就是暴力枚举的方法,但是这个题目还有一个注意的点是,这个数

组是递增的顺序,所以我们还可以优化这个暴力枚举。在昨天我们利用了数组的单调性解决了一个

问题,这个题目也可以利用这个单调性来解决。

这里我们来举个例子:

就利用这两个双指针,然后分为三种情况,和大于目标值,和小于目标值,和等于目标值。

看图中这种情况left所指的数加上right所指的数,加起来小于目标值,而中间这些数都是比right所

指的数小的,所以2不需要和这些数相加,因为肯定会小于目标数的,所以此时left此时指的数,不

会是最终结果,那么left++就行,再换一个区域去找即可:

        此时left加加,最后到7,加起来和还是小于目标值,所以left继续移动:

此时加起来和就超过了目标值,那么right所指的数就不对了,那么就right--,往前找小的数,让和

变小:

此时我们发现加起来的和正好为目标值,那么此时就找到了,就可以直接返回了。

这种算法原理,我们判断一次就可以干掉好多种情况,少掉好多次判断,时间复杂度就大大缩减,

这种时间复杂度就变为O(n)。

3.代码展示:

class Solution {
public:
    vectot<int>towSum(vector<int>& nums,int target){
        int left=0,right=nums.size()-1;
        while(left<right){
            int sum=nums[left]+nums[right];
            if(sum>t){
                right--;
            }else if(sum<t){
                left++;
            }
            else{
                return {nums[left],nums[right]};
            }
        }
       //如果编译器此时没有找到就也需要一个返回路径,所以随便返回两个数即可
        return {-1,-1};
    }
};

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

      1.题目描述:

           

这里题目的意思就是三个数的下标不一样,并且加起来要等于0那么这一组就叫三元组。

这里我们通过题目给的例子来分析一下题目的意思:

在题目给的例子,我们自己列出来了三种情况,但题目只返回了两种,因为我们列的第一种和第三

种虽然顺序不一样,但是因为里面的内容一样的,所以最后要舍去,所以接下来写代码也要考虑

到这一点。

2.算法原理:

    方法一:暴力解法

           就是用三层循环来找加起来的和为0的数。

           但是找很简单,我们还有一个重要的步骤就是去重,那么如何去去重呢,一开始想的是,把

和加起来为0的三元组里面的元素都排个序,然后再去看看,哪个重了,但是这样就更加麻烦了,

所以这里我们想到直接上来就给这个无序的数组先排序,然后再来暴力枚举可能会好一点。

例如:

 

这样我们看,这样排完序后再去找,直接就是一模一样的,不需要再去每一个三元组都去排序那么

麻烦,我们在C++学过set容器可以去重,直接放进去就可以。这样时间复杂度就是O(n^3),因为

只有这三重循环有时间复杂度,排序和去重都有相对于的函数和容器去弄,就相当于是一个常数的

时间复杂度。

  方法二:

         方法二也就是在暴力枚举的基础上去进行优化,减少时间复杂度。这里我们在暴力解法中,

已经讲数组排成有序的,那么既然是有序的,我们就想到了利用双指针算法,就去利用单调性去

来找。在和为s这道题我们是利用双指针解决的,这么是三个数相加和为0,那么我们也可以利用双

指针算法去解决这个问题。我们来看一个例子:

我们在暴力枚举里面是先固定一个数然后去找,那么在这里我们也先固定一个数,去找:

那么既然这样我们就固定第一个数去找,那么问题就转变成了在我画的这个区间去找两个数和为4

的数,就转变成了和为s的两个数字的那个题目的解法。正好-4+4=0.那么此时再利用双指针去找,

这里去找还有个可以优化,如果固定的数大于0,那么找的两数之和肯定不会是负数,因为是从小

到大的顺序排列的数组

在处理细节上不漏掉能构成的数组的情况比较好解决,那么就是在和为s的两个数字的题目中,我

们是找到了就返回,那么现在我们找到了还不能返回,要让left和right同时减减,这样才能做到情

况不漏。所以找到一种结果不能立马返回,不能停,两边都缩小区间去继续找。

既然不漏掉情况这个细节已经处理完毕了,去重怎么办呢,因为我们已经排好序了:

比如我已经在里面找到了0,4两个数据,因为已经排好序了,所以相等的值就在后面,如果后面的

值相等,我们就++,--过去,不考虑重复的数。既然里面去重了,外面固定的数也要去重。这样才

能完美去重。例如第一个-4枚举完了,完美就不枚举下一个-4,就直接跳过去。

当我们处理完这两个细节,我们还要避免越界,因为如果所有元素都相等,一直跳,跳出界就也会

报错

当这两个细节处理好,那么这个题目就可以完美得到解决,最重要的就是这两个细节的处理。

3.代码展示:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
         vector<vector<int>> ret;
        //排序:
        sort(nums.begin(),nums.end());
        
        //利用双指针解决问题
        int n=nums.size();
        for(int i=0;i<n;)//固定一个数
        {
            //如果固定的数大于0,那么找的两数之和肯定不会是负数,因为是从小到大的顺序排列的数组
            if(nums[i]>0){
                break;
            }
            int left=i+1,right=n-1,target=-nums[i];
            while(left<right){
                if(nums[left]+nums[right]>target){
                    right--;
                }else if(nums[left]+nums[right]<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++;
            while(i<n&&nums[i]==nums[i-1]) i++;
        }
         return ret;
     }
};

这个代码有非常多的细节需要去注意,所有建议多看这个解题过程。

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

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

相关文章

PyQt5实战——UTF-8编码器UI页面设计以及按钮连接(五)

个人博客&#xff1a;苏三有春的博客 系类往期文章&#xff1a; PyQt5实战——多脚本集合包&#xff0c;前言与环境配置&#xff08;一&#xff09; PyQt5实战——多脚本集合包&#xff0c;UI以及工程布局&#xff08;二&#xff09; PyQt5实战——多脚本集合包&#xff0c;程序…

【网络面试篇】HTTP(2)(笔记)——http、https、http1.1、http2.0

目录 一、相关面试题 1. HTTP 与 HTTPS 有哪些区别&#xff1f; 2. HTTPS 的工作原理&#xff1f;&#xff08;https 是怎么建立连接的&#xff09; &#xff08;1&#xff09;ClientHello &#xff08;2&#xff09;SeverHello &#xff08;3&#xff09;客户端回应 &a…

【VScode】中文版ChatGPT编程工具-CodeMoss!教程+示例+快捷键

文章目录 1. 多模型选择2. 编辑快捷键3. 历史记录收藏 CodeMoss使用教程1. 安装CodeMoss插件2. 配置AI模型3. 使用快捷键4. 进行代码优化与解释5. 收藏历史记录 总结与展望 在当今快速发展的编程世界中&#xff0c;开发者们面临着越来越多的挑战。如何提高编程效率&#xff0c;…

JqGird 动态生成列使用

使用场景&#xff1a; 在工作用需要自定义动态生成列&#xff0c;通过选择下拉框&#xff0c;加载列&#xff0c;通过查询加载列对应的数据信息 当选择文件源任务显示三列 当选择数据源任务显示两列 处理方式&#xff1a; 1. 首先在刚进入界面时初始化控件 $("#pageGri…

STM32Fxx读写eeprom(AT24C16)

一.I2C 协议简介 I2C 通讯协议 (Inter &#xff0d; Integrated Circuit) 是由 Phiilps 公司开发的&#xff0c;由于它引脚少&#xff0c;硬件实现简单&#xff0c;可扩展性强&#xff0c;不需要 USART、CAN 等通讯协议的外部收发设备&#xff0c;现在被广泛地使用在系统内多个…

鸿蒙系统的优势 开发 环境搭建 开发小示例

HarmonyOS是面向多智能终端、全场景的分布式操作系统,为消费者提供跨终端的无缝体验.华为开发者联盟从HarmonyOS应用设计、开发、测试、推广变现等环节全方位助力开发者。 开发者可以通过以下步骤学习鸿蒙系统的开发&#xff1a; 基础理论学习&#xff1a; 了解鸿蒙系统概述&a…

「C/C++」C/C++的区别

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

Windows部署rabbitmq

本次安装环境&#xff1a; 系统&#xff1a;Windows 11 软件建议版本&#xff1a; erlang OPT 26.0.2rabbitmq 3.12.4 一、下载 1.1 下载erlang 官网下载地址&#xff1a; 1.2 下载rabbitmq 官网下载地址&#xff1a; 建议使用解压版&#xff0c;安装版可能会在安装软件…

el-table 滚动条重置 手动控制滚动条

最近在使用 el-table 的时候&#xff0c;出现一个问题&#xff1a; 表头过长的时候&#xff0c;会有左右滑动的操作&#xff0c;当我们把表格拉到最右侧&#xff0c;这个时候重新请求数据的话&#xff0c;表格位置还是在最右侧&#xff0c;不会恢复原位。 那我们想恢复原位&a…

推荐FileLink数据跨网摆渡系统 — 安全、高效的数据传输解决方案

在数字化转型的浪潮中&#xff0c;企业对于数据传输的需求日益增加&#xff0c;特别是在不同网络环境之间的文件共享和传输。为了满足这一需求&#xff0c;FileLink数据跨网摆渡系统应运而生&#xff0c;为企业提供了一种安全、高效的数据传输解决方案。 安全第一&#xff0c;保…

STl学习-迭代器

1.迭代器种类 这五种迭代器的声明如下&#xff1a; truct output_iterator_tag {};//输出迭代器 truct input_iterator_tag{ };//输入迭代器 truct forward iterator tag : public input iterator tag {};//向前迭代器 truct bidirectional iterator tag :public forward iter…

自适应对话式团队构建,提升语言模型代理的复杂任务解决能力

人工智能咨询培训老师叶梓 转载标明出处 如何有效利用多个大模型&#xff08;LLM&#xff09;代理解决复杂任务一直是一个研究热点。由美国南加州大学、宾夕法尼亚州立大学、华盛顿大学、早稻田大学和谷歌DeepMind的研究人员联合提出了一种新的解决方案——自适应团队构建&…

临街矩阵乘以自己转置的含义

总结: 临街矩阵* 邻接矩阵转置的(i,j) 位置表示有多少种线路从元素A跳转一条边最终落到元素j的路线. 这个也叫1_degree.

JavaEE-多线程初阶(3)

目录 1.线程的状态 1.1 NEW、RUNNABLE、TERMINATED 1.2 TIMED_WAITING 1.3 WAITING 1.4 BLOCKED 2.多线程带来的风险-线程安全&#xff08;重点&#xff09; 2.1 观察线程不安全的现象 2.2 分析产生该现象的原因 2.3 产生线程安全问题的原因 2.3.1 抢占式执行&#x…

江协科技STM32学习- P35 硬件I2C读写MPU6050

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

学习虚幻C++开发日志——定时器

官方文档&#xff1a;虚幻引擎中的Gameplay定时器 | 虚幻引擎 5.5 文档 | Epic Developer Community | Epic Developer Community 定时器 安排在经过一定延迟或一段时间结束后要执行的操作。例如&#xff0c;您可能希望玩家在获取某个能力提升道具后变得无懈可击&#xff0c;…

【简道云 -注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

【表格解决问题】EXCEL行数过多,WPS如何按逐行分别打印多个纸张中

1 问题描述 如图&#xff1a;我的表格行数太多了。打印在一张纸上有点不太好看 2 解决方式 Step01&#xff1a;先选中你需要打印的部分&#xff0c;找到【页面】->【打印区域】->【设置打印区域】 Step02&#xff1a;先选中一行&#xff0c;找到【插入分页符】 Step0…

提高交换网络可靠性之链路聚合

转载请注明出处 该实验为链路聚合的配置实验。 1.改名&#xff0c;分别将交换机1和交换机2改名为S1&#xff0c;S2&#xff0c;然后查看S1&#xff0c;S2的STP信息。以交换机1为例&#x1f447;。 2.交换机S1&#xff0c;S2上创建聚合端口&#xff0c;将端口加入聚合端口。以S…

SpringMVC笔记 一万字

此笔记来自于B站尚硅谷 文章目录 一、SpringMVC 简介1、什么是MVC2、什么是SpringMVC3、SpringMVC的特点 二、HelloWorld1、开发环境2、创建maven工程a>添加web模块b>打包方式&#xff1a;warc>引入依赖 3、配置web.xmla>默认配置方式b>扩展配置方式 4、创建请求…