不到十个例题带你拿下c++双指针算法(leetcode)

移动零问题

https://leetcode.cn/problems/move-zeroes/submissions/

1.题目解析

必须在原数组进行修改,不可以新建一个数组

非零元素相对顺序不变

2.算法原理

【数组划分】【数组分块】

这一类题会给我们一个数组,让我们划分区间,比如说这题,最后会划分为两个区间,前一段是非零元素,后一段是零,一般我们只要看到这样的特性,脑海里就应该想到用双指针算法来解决(利用数组下标充当指针)

定义两个指针:

两个指针的作用:

cur :从左往后扫描数组,遍历数组。

dest : 已处理的区间内,非零元素的最后一个位置

如何做到:

cur从前往后遍历的过程中:

1.遇到0元素:cur++;

2.遇到非零元素:

交换

相关知识:快速排序

双指针的思想其实就是快排的核心思想

class Solution {
public:void moveZeroes(vector<int>& nums) {for(int cur=0,dest=-1;cur<nums.size();cur++){if(nums[cur]){swap(nums[++dest],nums[cur]);}}}
};

 

复写零问题

https://leetcode.cn/problems/duplicate-zeros/

1.题目解析

长度固定:不能越界

在原始数组进行操作

2.算法原理:

解法:双指针算法 先根据异地操作,然后优化成双指针下的“就地操作”

根据异地操作,得出先模拟一遍复写的操作,然后从后向前进行覆盖,从前往后会发生覆盖多的值。

总结:

1.先找到最后一个复写的数

用双指针模拟一遍 cur=0,dest=-1;

先判断cur位置的值,决定dest向后移动几步,判断dest是否已经到了最后的位置,cur++;

2.从后向前进行操作

特例:数组越界

所以要加上一个步骤:处理越界

3.解题代码:

class Solution {
public:void duplicateZeros(vector<int>& arr) {int cur=0,dest=-1,n=arr.size();//先模拟while(cur<n){if(arr[cur]) dest++;else         dest+=2;if(dest>=n-1) break;cur++;}//判断边界if(dest==n){arr[n-1]=0;dest-=2;cur--;}//从后向前while(cur>=0){if(arr[cur]==0){arr[dest--]=0;arr[dest--]=0;cur--;}else arr[dest--]=arr[cur--];}}
};

 

快乐数问题

https://leetcode.cn/problems/happy-number/

1.题目解析

一直替换

分为两种情况:

变成一

无限循环

两种情况

2.算法原理

有没有发现,一直平方到最后,一定会成环

解法:快慢双指针

1.定义快慢双指针

2.慢指针每次向后移动一步,快指针每次走两步

3.判断相遇的时候的值即可

双指针只是一种思想,不需要一定定义双指针,在这个题中快指针就是平方两次,慢指针平方一次

为什么会一定会重复

证明方法:

鸽巢原理(抽屉原理):

n个巢穴 n+1个鸽子-->至少有一个巢穴里面的鸽子数量大于1

3.解题代码

class Solution {
public:int Sum(int n){int sum=0;while(n){int g=n%10;sum+=g*g;n/=10;}return sum;}bool isHappy(int n) {int slow=n,fast=Sum(n);while(slow!=fast){slow=Sum(slow);fast=Sum(Sum(fast));}return slow==1;}
};

盛水最多的容器

https://leetcode.cn/problems/container-with-most-water/

1.题目解析

只能水平放置,也就是找最大的矩形

2.算法原理

解法一:暴力枚举:双重循环

优点:想法简单

缺点:时间复杂度过高

解法二:头尾双指针:

v=h*w

宽度一直在减小,而高度有两种情况,变大或变小,在宽度一直在变小的情况下,我们高度必须选择更高的

3.解题代码


class Solution {
public:int maxArea(vector<int>& height) {int left=0,right=height.size()-1;int v=-1;while(left<right){int tv=min(height[left],height[right])*(right-left);v=max(tv,v);if(height[left]>height[right])  right--;else                            left++;}return v;}
};

和为s的两个数字问题

1.题目解析

有序数组

随意输出一对

2.算法原理

解法一:暴力枚举 双重循环 n^2复杂度

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

首尾相加

判断数值,如果大于目标值,right--反之left++,因为数组是有序的

3.解题代码

vector<int> twosum(vector &nums,int t)
{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 {num[left],nums[right]};}//照顾编译器return {-1,-1};
}

有效三角形个数

https://leetcode.cn/problems/valid-triangle-number/

1.题目解析

相同的不算一个

2.讲解算法原理

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

我们仅需要一个公式,就能判断是否能构成三角形:

如果我们已经知道三个数的大小顺序,只需要a+b>c(c是最大的数)

优化:先对整个数组排序

解法一:暴力枚举

for(i=0;i<n;i++)

for(j=i+1;j<n;j++)for(k=j+1;k<n;k++)check(i,j,k)

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

①先固定最大的数

②在最大的数的左区间里,使用双指针算法,快速统计

3.解题代码

class Solution {
public:int triangleNumber(vector<int>& nums) {int n=nums.size();int ret=0;sort(nums.begin(),nums.end());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;}
};

三数之和问题

https://leetcode.cn/problems/3sum/

1.题目解析

三个数的下标不同

答案不可重复(去重)

有可能没有答案

2.算法原理

解法一:先排序+暴力枚举+利用set去重o(n^3)

解法二:排序+双指针:

找到右边区间两数之和为左边数字的相反即可

1.排序

2.固定一个数a

3.在该数后边的区间,利用双指针的算法,快速找到和为-a的两个数

处理细节问题:

1.去重:

找到一种结果之后,left和right指针要跳过重复元素。

当使用完一次双指针算法之后,i也要跳过重复元素(避免越界)

2.不漏:

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

3。解题代码

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(),nums.end());vector<vector<int>> ret;int n=nums.size();for(int i=0;i<n;){if(nums[i]>0) break;int left=i+1,right=n-1,t=-nums[i];while(left<right){int sum=nums[left]+nums[right];if(sum<t) left++;else if(sum>t) right--;else{ret.push_back({nums[i],nums[left],nums[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;}
};

四数之和

https://leetcode.cn/problems/4sum/

1.题目解析

三数之和的进阶版本,基本算法原理和三数之和大差不差

2.算法原理

解法一:排序+暴力枚举

四个循环,绝对超时

解法二:排序+双指针

1.依次固定一个数i

2.在i后面的区间内,利用三数之和找到三个数,让他们三个的和等于target-i;

{

1.依次固定一个j

2.在j后边的区间里,利用“双指针找到两个数,使得这两个数之和等于target-i-j”

}

处理细节问题:

不重,不漏

3.解题代码:

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ret;//1.排序sort(nums.begin(),nums.end());//2.利用双指针解决问题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 aim=(long long)target-nums[i]-nums[j];while(left<right){int sum=nums[left]+nums[right];if(sum<aim) left++;else if(sum>aim) right--;else{ret.push_back({nums[i],nums[j],nums[left++],nums[right--]});//去重1while(left<right&&nums[left]==nums[left-1]) left++;while(left<right&&nums[right]==nums[right+1]) right--;}}//去重2j++;while(j<n&&nums[j]==nums[j-1]) j++;			}//去重3i++;while(i<n&&nums[i]==nums[i-1]) i++;}  return ret;}
};

觉得有帮助的惯用老爷麻烦点点关注!!!

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

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

相关文章

【机器学习】Nonlinear Independent Component Analysis - Aapo Hyvärinen

Linear independent component analysis (ICA) x i ( k ) ∑ j 1 n a i j s j ( k ) for all i 1 … n , k 1 … K ( ) x_i(k) \sum_{j1}^{n} a_{ij}s_j(k) \quad \text{for all } i 1 \ldots n, k 1 \ldots K \tag{} xi​(k)j1∑n​aij​sj​(k)for all i1…n,k1…K()…

VUE语法-$refs和ref属性的使用

1、$refs和ref属性的使用 1、$refs:一个包含 DOM 元素和组件实例的对象&#xff0c;通过模板引用注册。 2、ref实际上获取元素的DOM节点 3、如果需要在Vue中操作DOM我们可以通过ref和$refs这两个来实现 总结:$refs可以获取被ref属性修饰的元素的相关信息。 1.1、$refs和re…

PS_魔幻

首先打开一个背景图片 然后ctrl j复制一层背景 在调整中将图片改成黑白颜色 点击调整中的 色相/饱和度 调整明度 点击画笔工具&#xff0c;并且设置画笔模板 调节画笔大小&#xff0c;将笔记本电脑涂个概况 然后再新建色相/饱和度 勾选着色 调节背景颜色至喜欢 右键混合选项 …

04-React脚手架 集成Axios

初始化React脚手架 前期准备 1.脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目 1.包含了所有需要的配置&#xff08;语法检查、jsx编译、devServer…&#xff09;2.下载好了所有相关的依赖3.可以直接运行一个简单效果 2.react提供了一个用于创建react项目的脚手架库…

一键去水印免费网站快速无痕处理图片、视频水印

水印问题往往是一个大麻烦。即使我们只想将这些照片保留在我们的个人相册中以供怀旧&#xff0c;水印也可能像顽固的符号一样刺激我们的眼睛。为了解决这个问题&#xff0c;我们需要不断探索创新的解决方案&#xff0c;让我们深入研究一款强大的一键去水印免费网站“水印云”。…

Rust并发编程:理解线程与并发

大家好&#xff01;我是lincyang。 今天我们来深入探讨Rust中的并发编程&#xff0c;特别是线程的使用和并发的基本概念。 Rust中的线程 Rust使用线程来实现并发。线程是操作系统可以同时运行的最小指令集。在Rust中&#xff0c;创建线程非常简单&#xff0c;但与此同时&…

二叉搜索树java实现

顾名思义&#xff0c;二叉搜索树是一棵二叉树&#xff0c;每个节点就是一个对象&#xff0c;这个对象包含属性left、right和parent。left指向节点的左孩子&#xff0c;right指向节点的右孩子&#xff0c;parent指向节点的父节点&#xff08;双亲&#xff09;。如果某个孩子节点…

黑马点评笔记 redis实现缓存

文章目录 什么是缓存?为什么要使用缓存 如何使用缓存功能实现缓存模型和思路代码实现 缓存更新策略数据库缓存不一致解决方案代码实现 什么是缓存? 缓存(Cache),就是数据交换的缓冲区,俗称的缓存就是缓冲区内的数据,一般从数据库中获取,存储于本地代码(例如: 例1:Static fi…

vr小鼠虚拟解剖实验教学平台减少了受感染风险

家畜解剖实验教学是培养畜牧兽医专业学生实际操作能力的专业教学活动中的核心手段。采取新型教学方式与手段&#xff0c;合理设置实验教学内容&#xff0c;有助于激发学生的操作积极性&#xff0c;促进实践教学的改革。 家畜解剖VR仿真教学是一种借助VR虚拟现实制作和web3d开发…

常用通信接口、协议:SCCB

一、概述 SCCB(串行摄像头控制总线)是由欧姆尼图像技术公司&#xff08;OmniVision&#xff09;开发的一种类IIC的总线&#xff0c;主要用于其OV系列的图像传感器上&#xff08;但目前有很多家的图像传感器都有采用该控制总线&#xff09;。相对于IIC总线来说SCCB与之最主要的差…

java基础-集合

1、集合 在java中&#xff0c;集合&#xff08;Collection&#xff09;指的是一组数据容器&#xff0c;它可以存储多个对象&#xff0c;并且允许用户通过一些方法来访问与操作这些对象。j 集合的实现原理都基于数据结构和算法&#xff0c;如下&#xff1a; 数据结构&#xff1…

振南技术干货集:制冷设备大型IoT监测项目研发纪实(2)

注解目录 1.制冷设备的监测迫在眉睫 1.1 冷食的利润贡献 1.2 冷设监测系统的困难 &#xff08;制冷设备对于便利店为何如何重要&#xff1f;了解一下你所不知道的便利店和新零售行业。关于电力线载波通信的论战。&#xff09; 2、电路设计 2.1 防护电路 2.1.1 强电防护 …

基于JavaWeb+SSM+Vue教学辅助微信小程序系统的设计和实现

基于JavaWebSSMVue教学辅助微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 1.1 概述 随着信息时代的快速发展&#xff0c;互联网的优势和普及&#xff0c;人们生活…

[项目管理-33/创业之路-87/管理者与领导者-127]:如何提升自己项目管理的能力和水平

目录 前言&#xff1a; 一、项目经理的角色定位 1.1 项目经理的职责 1.2 不同矩阵类型的项目&#xff0c;项目经理的职责 1.3 项目经理的角色定位 1.4 项目经理的发展路径 二、项目经理项目理论和知识结构 三、软件项目经理在计算机水平的提升 四、项目经理业务知识的…

nodejs微信小程序+python+PHP-储能电站运营管理系统的设计与实现-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

七、通过libfdk_aac编解码器实现aac音频和pcm的编解码

前言 测试环境&#xff1a; ffmpeg的4.3.2自行编译版本windows环境qt5.12 AAC编码是MP3格式的后继产品&#xff0c;通常在相同的比特率下可以获得比MP3更高的声音质量&#xff0c;是iPhone、iPod、iPad、iTunes的标准音频格式。 AAC相较于MP3的改进包含&#xff1a; 更多的采…

系列八、key是弱引用,gc垃圾回收时会影响ThreadLocal正常工作吗

一、key是弱引用&#xff0c;gc垃圾回收时会影响ThreadLocal正常工作吗 到这里&#xff0c;有些小伙伴可能有疑问&#xff0c;ThreadLocalMap的key既然是 弱引用&#xff0c;那么GC时会不会贸然地把key回收掉&#xff0c;进而影响ThreadLocal的正常使用呢&#xff1f;答案是不会…

HTML新手入门笔记整理:HTML基本标签

结构标签 <html> </html> 告诉浏览器这个页面是从<html> 开始&#xff0c;到 </html>结束 <head> </head> 网页的头部&#xff0c;用于定义一些特殊内容&#xff0c;如页面标题、定时刷新、外部文件等。 <body> </body> …

基于SSM的旅游管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

数据分析基础之《matplotlib(1)—介绍》

一、什么是matplotlib 1、专门用于开发2D图表&#xff08;包括3D图表&#xff09; 2、使用起来及其简单 3、以渐进、交互方式实现数据可视化 4、matplotlib mat&#xff1a;matrix&#xff08;矩阵&#xff09; plot&#xff1a;画图 lib&#xff1a;库 二、为什么要学习m…