【刷题】双指针进阶

news2024/12/25 2:22:48

在这里插入图片描述
请看入门篇 :双指针入门
送给我们一句话:
如今我努力奔跑,不过是为了追上那个曾经被寄予厚望的自己 —— 约翰。利文斯顿

双指针进阶

  • Leetcode 611 有效三角形的个数
  • Leetcode LCR179.查找总价格为目标值的两个商品
  • Leetcode 15.三数之和
  • Thanks♪(・ω・)ノ谢谢阅读!!!
  • 下一篇文章见!!!

今天我继续学习了双指针的题目,继续探索了双指针的进阶用法。其中包括对撞指针,单调性分析指针。接下来我带大家一起复盘一下我做的三道题目,来深入了解一下双指针算法的进阶版本。在入门篇中我们基本知道了双指针的思路,即控制两个指向分别按条件转换,这样配合排序算法可以大大降低算法的时间复杂度。
而接下来我们继续学习,来看看双指针对复杂问题的解决。

Leetcode 611 有效三角形的个数

在这里插入图片描述
来看看给出的测试用例:

  1. 输入: nums = [2,2,3,4]
  2. 输出: 3
  3. 解释:有效的组合是:
    1. 2,3,4 (使用第一个 2)
    2. 2,3,4 (使用第二个 2)
    3. 2,2,3

根据题目和样例,这是一个看起来十分简单的题目,让小学生来解决也有可能,毕竟大家都会使用最直接了当的暴力解法,遍历整个数组,筛选出满足的三角形即可。下面我们使用伪代码来简单写一下思路:

for(int i = 0;i < n - 2; i++){
	for(int j = i + 1 ; j < n - 1; j++){
		for(int k = j + 1 ;k < n;k++){
			check(num[i],num[j],num[k]);
		}
	}
}

很显然,这样的算法时间复杂度是O( n^ 3),非常非常非常不理想。
那如何把双指针使用到里面呢?
首先我们来看check的过程:
思路与算法

对于正整数 a,b,c它们可以作为三角形的三条边,当且仅当:

a+b>c
a+c>b
b+c>a

均成立。如果我们将三条边进行升序排序,使它们满足 a≤b≤c,那么 a+c>b 和b+c>a 使一定成立的,我们只需要保证 a+b>c。所以我们只需要比较较小的两个数和最大是否满足即可。

所以现在我们有了一个初步的想法:

  1. 先对容器元素进行排序
  2. 从最大值开始依次作为最大值 num1 来找三角形
  3. 这时开始使用双指针的思想,分别取0(left)下标位置的 num2 和 num1 左边第一个(right)元素 num3,进行比较
  4. 使用单调性判断:
    1. 如果 num2 + num3 > num1 三角形成立,则left 到 right之间的元素都满足 (根据单调性判 断)
    2. 如果 num2 + num3 <= num1那么三角形不成立,那么就要右移 left 来使 num2 + num3更大一些,
  5. 依次往复,就解决问题了。

来看代码:

//比较函数
int compare(int i,int j){
    return i < j;
} 
class Solution {
public:

    int triangleNumber(vector<int>& nums) {
        //首先排序,优化容器
        //取一个固定的较大数
        //在左区间进行查找,利用单调性
        sort(nums.begin(),nums.end(),compare);
        int count = 0;  
        int  m = nums.size() - 1;
        while(m >= 2){
            int max = nums[m];
            int left = 0,right = m - 1;

            while(left <= right){
            	//左值是0直接跳过
            	//右值是零直接跳出循环(有0不可能成立)
                if(nums[right] == 0) break;
                while (nums[left] == 0) left++; 
                int sum = nums[left] + nums[right];
                if(sum > max) {
                    count += right - left;
                    right--;
                } else left++;
            }
            //每次m 需要进行移动。
            m--;
        }
        return count;
    }
};

这样我们就成功解决了问题。来看运行的效果:
在这里插入图片描述
击败 93.48%,我们非常快速!!!(如果使用暴力算法,就直接超时了)
所以双指针的算法是非常高效的算法,并且一般有序问题都可以进行求解!

Leetcode LCR179.查找总价格为目标值的两个商品

在这里插入图片描述

这道题是十分经典的题目,来自剑指offer 的和为 s 的两个数,让我们来看看吧
根据题目描述,也是比较简单的问题,我们一样来进行单调性分析:

  1. 首先也是进行排序
  2. 使用两个指向 left num1 和 right num2 分别从左右开始
  3. 来分析结果:
    1. num1 + num2 == target 直接返回即可
    2. num1 + num2 > target 说明较大,那么right左移即可
    3. num1 + num2 < target 说明较小,那么left右移即可
  4. 直到找到结果就好

来看代码:


class Solution {
public:
   vector<int> twoSum(vector<int>& price, int target) {
      //分别从左右开始遍历
       int left = 0;
       int right = price.size()-1;

       while(left < right){
           int sum = price[left] + price[right];
           //三种结果分析好
           if(sum > target) right--;
           else if(sum < target) left++;
           //返回vector类型 ,使用 { } 包括即可
           else return{price[left] , price[right]};
       }
       //照顾编译器,不然报错
       return {-1,-1};
   }
};

我们这样也成功通过测试用例,完成题目!!!
思路非常直接了当。

Leetcode 15.三数之和

在这里插入图片描述

我们先来看给出的样例:

  1. 输入:nums = [-1,0,1,2,-1,-4]
  2. 输出:[[-1,-1,2],[-1,0,1]]
  3. 解释:
    nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
    nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
    nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
    不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
    注意,输出的顺序和三元组的顺序并不重要。

根据我们的最直接的想法就是遍历,但是我们都知道这样十分复杂,哈哈哈哈
我们来看这道题和判断三角形是不是很像,三角形是要求num1 + num2 > num3,
而这题要求我们num1 + num2 == num3,所以基础的双指针框架是十分相似的,我们可以先写出一个框架来:

class Solution {
public:
   vector<vector<int>> threeSum(vector<int>& nums) {
       //先使数据有序
       sort(nums.begin(),nums.end());
       vector<vector<int>> ans;
   	//开始遍历,取最大数
       int m = nums.size() - 1;
       //从 最大值 开始
       while(m >= 2){
   	
           int left = 0 , right = m - 1;
           int num1 = nums[m];
           //双指针进行
           while(left < right){
   			//左值右值进行初始化
               int num2 = nums[left] , num3 = nums[right];
               //进行判断
               
               if(num2 + num3 + num1 == 0){
               //满足就进行插入
                   ans.push_back({num2,num3,num1}) ;
                       left++;
                       right--;
               } 
               else if(num2 + num3 + num1 < 0) {
                       left++;
               }
               else if(num2 + num3 + num1 > 0) {
                       right--;
               }
           }
               //m 向左移动
               m--;
       }
       return ans;
   }
};

这样提交后:我们只看这一个样例:在这里插入图片描述

发现有好多重复的,这应该怎麽办??????
我的想法是从根源出发,既然我们排好序了就直接每次选中一组后,把相应元素都跳过!!!
不满足的也一次性全部都跳过!!!直接了当

这样一定一定不会有重复的出现!!!

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    	 //先使数据有序
        sort(nums.begin(),nums.end());
        vector<vector<int>> ans;
		//从最大值开始遍历
        int m = nums.size() - 1;
        while(m >= 2){
			//左右值进行初始化
            int left = 0 , right = m - 1;
            int num1 = nums[m];
            while(left < right){

                int num2 = nums[left] , num3 = nums[right];
                
                if(num2 + num3 + num1 == 0){
                    ans.push_back({num2,num3,num1}) ;
                    //满足条件直接全部都跳过!!!
                    while(nums[left] == num2 && left < right){
                        left++;
                    }
                    while(nums[right] == num3 && left < right){
                        right--;
                    }
                    
                } 

                else if(num2 + num3 + num1 < 0) {
                //不满足条件的都跳过!!!
                    while(nums[left] == num2 && left < right){
                        left++;
                    }

                }
                else if(num2 + num3 + num1 > 0) {
                 //不满足条件的都跳过!!!
                    while(nums[right] == num3 && left < right){
                        right--;
                    }
                }
            }
            //满足的 m 也都跳过!!!
            while(nums[m] == num1 && m > 0){
                m--;
            }

        }
        return ans;
    }
};

这样我们完成里去除重复的元素!!!!!!
把最复杂的问题简化到了每个步骤里面:
来看效果:
在这里插入图片描述
还不错!!!

送给大家一句话:
如今我努力奔跑,不过是为了追上那个曾经被寄予厚望的自己 —— 约翰。利文斯顿

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

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

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

相关文章

uniapp中人脸识别图片并圈起人脸

效果如上&#xff0c;我用的是阿里云的人脸识别。首先&#xff0c;我们先封装一个阿里云的请求js文件 faceRecognition.js import CryptoJS from crypto-js//SignatureNonce随机数字 function signNRandom() {const Rand Math.random()const mineId Math.round(Rand * 1000…

UE5 android打包

下载安装JDK https://repo.huaweicloud.com/java/jdk/https://repo.huaweicloud.com/java/jdk/ 选择对应的jdk版本 配置环境变量 编辑Path 验证是否成功 java -version 安装Android Studio https://developer.android.google.cn/studio?hlzh-cnhttps://developer.androi…

EMQX 4.0和EMQX 5.0集群架构实现1亿MQTT连接哪些改进

EMQX 5.0水平扩展能力得到了指数级提升&#xff0c;能够更可靠地承载更大规模的物联网设备连接量。 在EMQX5.0正式发布前的性能测试中&#xff0c;我们通过一个23节点的EMQX集群&#xff0c;全球首个达成了1亿MQTT连接每秒100万消息吞吐&#xff0c;这也使得EMQX 5.0成为目前为…

【C++ 设计模式】简单工厂模式

文章目录 前言一、简单工厂模式是什么&#xff1f;二、实现原理三、UML类图四、简单工厂模式具体代码总结 前言 在软件开发中&#xff0c;设计模式是解决特定问题的可复用解决方案。其中&#xff0c;简单工厂模式是一种创建型设计模式&#xff0c;旨在封装对象的创建过程&…

IDEA开启Run Dashboard

1、Run Dashboard是什么&#xff0c;为什么要使用 Run Dashboard 是 IntelliJ IDEA 中的一个工具窗口&#xff0c;用于管理和监视项目中正在运行的应用程序和配置。它提供了一种集中管理运行和调试过程的方式&#xff0c;可以让开发人员更方便地查看和控制正在运行的应用程序。…

2 Redis的安装与配置

这里是要将 Redis 安装到 Linux 系统中。 1.1 Redis 的安装 1.1.1 克隆并配置主机 修改主机名&#xff1a;/etc/hostname修改网络配置&#xff1a;/etc/sysconfig/network-scripts/ifcfg-ens33 1.1.2 安装前的准备工作 &#xff08;1 &#xff09;安装 gcc &#xff08;2…

如何从 Mac 电脑外部硬盘恢复删除的数据文件

本文向您介绍一些恢复 Mac 外置硬盘数据的快速简便的方法。 Mac 的内部存储空间通常不足以存储所有数据。因此&#xff0c;许多用户通过外部驱动器扩展存储或创建数据备份。然而&#xff0c;与几乎所有其他设备一样&#xff0c;从外部硬盘驱动器丢失有价值的数据并不罕见。由于…

数据库是什么?数据库连接、管理与分析工具推荐

一、数据库是什么&#xff1f; 数据库是一种结构化的数据存储系统&#xff0c;用于有效地组织、存储和管理大量的数据。它是一个集中化的数据存储库&#xff0c;通常由一个或多个数据表组成&#xff0c;每个数据表包含多个行和列&#xff0c;用于存储特定类型的数据。数据表中…

SQLiteC/C++接口详细介绍之sqlite3类(七)

上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;六&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍之sqlite3类&#xff08;八&#xff09;&#xff08;未发表&#xff09; 22.sqlite3_create_collation、sqlite3_create_collation16和sqlite3_creat…

【java工具】Maven的下载配置+setting配置(以3.9.6为例)

本人正在学习spring&#xff0c;还是个小白&#xff0c;也是跟着网课和各种资料学&#xff0c;光学习spring项目的各种配置就花了我不少时间QWQ。在学习spring的每个阶段&#xff0c;我会做好技术总结&#xff0c;不定期分享出来&#xff0c;希望对你有所帮助&#xff0c;有问题…

【Node.js从基础到高级运用】十二、身份验证与授权:JWT

身份验证与授权是现代Web应用中不可或缺的部分。了解如何在Node.js应用中实施这些机制&#xff0c;将使你能够构建更安全、更可靠的应用程序。本文将引导你通过使用JWT实现用户注册、登录和权限控制的过程。 JWT&#xff08;Json Web Token&#xff09; JWT是一种用于双方之间…

COX回归影响因素分析的基本过程与方法

在科学研究中&#xff0c;经常遇到分类的结局&#xff0c;主要是二分类结局&#xff08;阴性/阳性&#xff1b;生存/死亡&#xff09;&#xff0c;研究者可以通过logistic回归来探讨影响结局的因素&#xff0c;但很多时候logistic回归方法无法使用。如比较两种手段治疗新冠肺炎…

报表生成器FastReport .Net用户指南:关于脚本(上)

FastReport的报表生成器&#xff08;无论VCL平台还是.NET平台&#xff09;&#xff0c;跨平台的多语言脚本引擎FastScript&#xff0c;桌面OLAP FastCube&#xff0c;如今都被世界各地的开发者所认可&#xff0c;这些名字被等价于“速度”、“可靠”和“品质”,在美国&#xff…

hive-批量导出表结构,导入表结构

1、导出hive表结构 datastudio可以连接hive库&#xff0c;通过show databases 语句可以显示hive下建了多少数据库名。 使用use 数据库名&#xff0c;进入某个数据库下&#xff0c;通过show tables可显示该数据库下建了多少张表。 将所有库的表数据整理成库名.表名的形式放入…

python基于flask考研学习交流系统30vy7附源码django

考研在线学习与交流平台根据实际情况分为前后台两部分&#xff0c;前台部分主要是让用户使用的&#xff0c;包括用户的注册登录&#xff0c;首页&#xff0c;课程信息&#xff0c;在线讨论&#xff0c;系统公告&#xff0c;后台管理&#xff0c;个人中心等功能&#xff1b;后台…

Qt_vc++崩溃日志分析

环境 Clion &#xff1a;2019.3.6 Qt &#xff1a;5.9.6&#xff08;vc2015&#xff09; 编译工具&#xff1a;vs2015 update3 崩溃日志收集 自行百度&#xff0c;会查到很多&#xff0c;一下代码仅供参考&#xff08;来自https://blog.csdn.net/weixin_45571586/article/…

java的23种设计模式02-创建型模式02-抽象工厂方法

一、抽象工厂方法 1-1、抽象工厂方法的定义 抽象工厂模式是一个比较复杂的创建型模式。 抽象工厂模式和工厂方法不太一样&#xff0c;它要解决的问题比较复杂&#xff0c;不但工厂是抽象的&#xff0c;产品是抽象的&#xff0c;而且&#xff1a;有多个产品需要创建&#xff…

HTML案例-2.标签综合练习

目录 效果 知识点 1.图像标签 2.链接标签 3.锚点定位 4.base标签 源码 页面1 页面2 效果 知识点 1.图像标签 <img src="图像URL" /> 单标签 属性 属性值 描述 src URL 图像的路径 alt 文本

导入csv文件表头字符串出现zwnbsp字符(零宽度空白字符)处理

导入csv文件表头字符串出现zwnbsp字符&#xff08;零宽度空白字符&#xff09;处理 【1】现象描述【2】问题分析【3】原因分析【4】问题解决&#xff08;1&#xff09;修改文件的编码格式&#xff08;2&#xff09;在代码中处理 【1】现象描述 通过easyexcel导入csv文件&#…

9种分布式ID生成之美团(Leaf)实战

​​​​​ 前几天写过一篇《一口气说出 9种 分布式ID生成方式&#xff0c;面试官有点懵了》&#xff0c;里边简单的介绍了九种分布式ID生成方式&#xff0c;但是对于像美团&#xff08;Leaf&#xff09;、滴滴&#xff08;Tinyid&#xff09;、百度&#xff08;uid-generator&…