专题一——双指针算法

原理:将数组进行区间划分,通过指针(下标)的移动实现题目所要求的区间(数组分块

(实现代码统一是C++)

建议在做题与看题解时要自己反复模拟这个实现的过程,以后在做题做到类似的题才能举一反三!

一移动零

链接:283. 移动零 - 力扣(LeetCode)

思路:将要实现的区间用指针划为不同的区间(非0区间与0区间)再进行指针的搜索。

class Solution {
public:void moveZeroes(vector<int>& nums) {int cur=-1,des=0;//cur固定,des去进行数组的扫描,即找非0元素//最后:[0,cur]为非0元素[cur+1,des]为0元素while(des<nums.size()){if(nums[des]!=0){swap(nums[cur+1],nums[des]);cur++;}des++;}}
};

二复写零

链接:1089. 复写零 - 力扣(LeetCode)

思路:

确定目标位置:首先,使用两个指针 dest 和 cur 来确定每个位置复制0后应该放置的位置。cur 指针用于遍历原始数组,而 dest 指针则用于确定在复制0后应该放置新元素的位置。

cur 最终的位置就是复写后数组的最后一个数的位置。

再从后往前进行数组值的覆盖(从前向后遍历会导致数组后面元素丢失)

class Solution {
public:void duplicateZeros(vector<int>& arr) {int cur=0,des=-1,n=arr.size();while(des<n){//arr[cur+1]==0...如果在cur=0位置上是0呢?if(arr[cur]==0){des+=2;}else{des++;}if(des>=n-1){break;}cur++;}//[1,0,2,3,0,4]des走到n位置越界if(des>n-1){//直接让des在数组的最后一个位置上并把它赋为0(越界情况一定是在复写0的时候越界的!)des=n-1;arr[des--]=0;cur--;}//cur的位置是要实现的数组的最终位置while(cur>=0){//(cur的位置遇到0就让des进行复写0的操作)if(arr[cur]==0){arr[des--]=0;arr[des--]=0;cur--;}//从后向左进行值的覆盖else{arr[des--]=arr[cur--];}}}
};

三快乐数

链接:202. 快乐数 - 力扣(LeetCode)

思路:由于鸽巢原理,最后必定会有两个数相等,形成闭环即:在某一时刻,只有两种情况:要么有数字等于1形成闭环,要么会有两个数是相等的!

那么我们可以使用在环形链表中一样使用快慢双指针来进行解答 

class Solution {
public://函数实现每一位数平方和相加int bitsum(int n){int sum=0;while(n){sum+=pow(n%10,2);n/=10;}return sum;}//类似环形链表首先想到快慢双指针//不管最后有没有结果等于1,都一定会有两个数相等形成闭环(重复循环)//slow与fast一定在某个时刻相等 bool isHappy(int n) {int slow=n,fast=n;while(slow!=1){slow=bitsum(slow);fast=bitsum(bitsum(fast));if(slow==fast){break;}}return slow==1;}
};

四盛最多水的容器

oj链接:11. 盛最多水的容器 - 力扣(LeetCode)

 思路:使用两个指针,一个在最左一个在最右,算出结果进行调整移动时,要移动两个中最小的那一个(短板效应),在各种结果中找出最大的容器即为题目所求

class Solution {
public:int maxArea(vector<int>& height) {//ret存储的是最多容纳的水int left=0,right=height.size()-1,ret=INT_MIN;while(left<right){//更新ret的值始终保持是所有盛水容器当中最大的ret=max(ret,(right-left)*min(height[left],height[right]));//要去移动最小的高//如果是移到最大的:距离在减小(高度是按最小的来算的),结果只会是减不会增if(height[left]<height[right]){left++;}else{right--;}}return ret;}
};

五有效三角形的个数 

oj链接:611. 有效三角形的个数 - 力扣(LeetCode)

思路:先对数组进行排升序,排序后要先固定最大的那个值,然后就可以用双指针算法来解决问题:(与上面的思路大致相同) 

class Solution {
public:int triangleNumber(vector<int>& nums) {//先将数组进行排升序sort(nums.begin(),nums.end());int count=0,left=0,right=0;//固定最后一个数(最大的数nums[i])for(int i=nums.size()-1;i>=0;i--){//一定left,最大的数左边right进行移动left=0,right=i-1;while(left<right){//两个数相加<=最大的数则要移动left使得和变大if(nums[left]+nums[right]<=nums[i]){left++;}else{//left向后无论怎么移动,和一定>nums[i]即满足三角形任意两者之和大于第三边count+=right-left;right--;}}}return count;}
};

六 寻找总价格为目标值的两个商品

 oj链接:LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode)

思路与上面大体一致,比较简单这里就不写了

class Solution {
public:vector<int> twoSum(vector<int>& price, int target) {vector<int> ans;int left=0,right=price.size()-1;while(left<right){if(price[left]+price[right]<target){left++;}else if(price[left]+price[right]>target){right--;}else{ans.push_back(price[left]);ans.push_back(price[right]);break;}}return ans;}
};

七三数之和

oj链接:LCR 007. 三数之和 - 力扣(LeetCode)

思路:与有效三角形的个数类似:先固定一个数,再使用双指针进行移动找到:nums[left]+nums[right]==-固定数。但实现起来要考虑两个细节:

1不漏:在找到符合值后,两个指针不要‘停’,继续靠拢进行查找;

2去重:找到后要判断在接下来移动的时候是否会遇到重复数(遇到就直接跳过)

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(),nums.end());//C++直接开辟二维数组vector<vector<int>> ans;int left=0,right=0,n=nums.size();//固定最左边一个数,在利用二数先加的题的思路去实现//但要考虑:1不漏 2去重for(int i=0;i<n;){if(nums[i]>0){break;}left=i+1,right=n-1;while(left<right){if(nums[left]+nums[right]>-nums[i]){right--;}else if(nums[left]+nums[right]<-nums[i]){left++;}else{//C语言要开辟数组,这里直接push_back爽!!ans.push_back({nums[left],nums[right],nums[i]});//不漏left++,right--;//去重,判断while循环条件先在后面,否则会有越界风险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 ans;}
};

对比用C语言写的:要进行对二维数组的开辟,非常麻烦!

/*** Return an array of arrays of size *returnSize.* The sizes of the arrays are returned as *returnColumnSizes array.* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().*/int cmp(const void * a, const void * b)
{return ( *(int*)a - *(int*)b );
}
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){*returnSize=0;//初始化//排序qsort(nums,numsSize,sizeof(int),cmp);//为规定的返回值创建类型相同的数组int** ans=(int**)malloc(sizeof(int*)*numsSize*numsSize);//返回数组的数组要malloc*returnColumnSizes=(int*)malloc(sizeof(int)*numsSize*numsSize);//参考两数之和利用双指针算法,但要考虑去重,数组越界问题for(int i=0;i<numsSize;){int begin=i+1,end=numsSize-1,target=nums[i];//如果固定的值>0,那么三数相加就不可能=0(小优化)if(target>0) break;//在固定值后,在[begin,end]的区间内进行查找while(begin<end){if(nums[begin]+nums[end]==-target){//二级数组ans中malloc存储三元数组的值(类似坐标的方式进行表达)ans[*returnSize]=(int*)malloc(sizeof(int)*3);//要返回数量的大小(*returnColumnSizes)[*returnSize]=3;ans[*returnSize][0]=nums[begin];ans[*returnSize][1]=nums[end];ans[*returnSize][2]=target;(*returnSize)++;begin++;end--;//[0,0,0,0,0]while(begin<end && nums[begin]==nums[begin-1]) begin++;while(begin<end && nums[end]==nums[end+1]) end--;}else if(nums[begin]+nums[end]>-target) end--;else if(nums[begin]+nums[end]<-target) begin++;}i++;while(i<numsSize && nums[i]==nums[i-1]) i++;}return ans;
}

 八四数之和

oj链接:18. 四数之和 - 力扣(LeetCode)

思路:与三数之和类似,多个固定的数和溢出问题的解决

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {sort(nums.begin(),nums.end());vector<vector<int>> ans;int left=0,right=0,n=nums.size(),sum=0;for(int i=0;i<n;){for(int j=i+1;j<n;){left=j+1,right=n-1;//处理数据溢出long long aim=(long long)target-nums[i]-nums[j];while(left<right){sum=nums[left]+nums[right];if(sum<aim){left++;}else if(sum>aim){right--;}else{ans.push_back({nums[left],nums[right],nums[i],nums[j]});left++,right--;while(left<right&&nums[left]==nums[left-1]){left++;}while(left<right&&nums[right]==nums[right+1]){right--;}}}j++;while(j<n&&nums[j]==nums[j-1]){j++;}}i++;while(i<n&&nums[i]==nums[i-1]){i++;}}return ans;}
};

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

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

相关文章

git基础-记录对仓库的更改

记录对仓库的更改 到目前为止&#xff0c;我们应该在本地计算机上拥有一个真正的 Git 仓库&#xff0c;并且拥有所有文件的一个检出或工作副本。通常&#xff0c;我们会想要开始进行更改&#xff0c;并在项目达到想要记录的状态时&#xff0c;将这些更改的快照提交到我们仓库中…

【数字图像处理系列】读取图像

【数字图像处理系列】读取图像 使用函数 imread 可以将图像读人 MATLAB 环境&#xff0c;imread 的语法为 imread(filename)其中&#xff0c;filename是一个含有图像文件全名的字符串(包括任何可用的扩展名)。例如&#xff0c;命令行 >>f imread(pout.tif)将tif图像po…

【面试经典150 | 数组】分发糖果

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;贪心两次遍历 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容…

慧哥充电桩平台 二轮电动自行车 四轮汽车 云快充1.5 云快充1.6

文章目录 一、产品功能部分截图1.手机端&#xff08;小程序、安卓、ios&#xff09;2.PC端 二、小程序体验账号以及PC后台体验账号1.小程序体验账号2.PC后台体验账号关注公众号获取最新资讯 三、产品简介&#xff1f;1. 充电桩云平台&#xff08;含硬件充电桩&#xff09;&…

Redis相关操作高阶篇--集群搭建

Redis相关操作大全一篇全搞定-CSDN博客 Redis集群 是一个由多个主从节点群组成的分布式服务器群&#xff0c;它具有复制、高可用和分片特性。Redis集群不需要seninel哨兵也能完成节点移除和故障转移的功能。需要将每个节点 设置成集群模式&#xff0c;这种集群模式没有中心节…

vulnhub打靶记录——Mycmsms

文章目录 一、环境布置主机发现 二、端口扫描nikto基本探测目录扫描CMS EXP搜索探查mysql数据库CMS代码审计CMS后台权限提升 一、环境布置 靶机在virtualbox中搭建&#xff0c;攻击机使用vmware中安装的kali&#xff0c;主要是解决kali能ping通靶机&#xff0c;同时能访问外网…

Qt扫盲-D-Bus调试工具

D-Bus调试工具 一、概述二、安装d-feet三、使用d-feet 一、概述 在调试D-Bus时&#xff0c;如果只是在命令行下使用&#xff0c;效率并不是很高&#xff0c;我们可以使用更加直观的GUI工具来查看&#xff0c;我推荐使用 d-feet工具&#xff0c;这个能直观的查看系统总线和会话…

企业异地组网的挑战与解决方案

在当今互联的商业环境中&#xff0c;建立跨越不同地点的网络变得至关重要。本文将探讨企业异地组网的复杂性&#xff0c;并提供实用解决方案以应对这些挑战。通过了解创新技术如SD-WAN和网络安全措施&#xff0c;确保企业异地组网在性能和数据完整性方面的最佳表现。 由于距离和…

用例图画法

介绍 在软件工程中&#xff0c;用例图是一种用于描述系统功能和与之交互的参与者&#xff08;Actors&#xff09;之间关系的图形表示方法。 绘图步骤 确定参与者&#xff08;Actors&#xff09;&#xff1a;识别系统中的各个参与者&#xff0c;这些参与者可以是人、其他系统或外…

unity学习(63)——预制体

1.运行发现预制体初始化的时候存在问题 这里有许多技巧&#xff0c;需要细看。 2.预制体在MapHandler.cs的定义如下 3.把MapHandler绑到相机上&#xff0c;在相机的属性栏中找到赋值部分。 4.size设置成2&#xff0c;然后把模型拖拽到1号索引位置上 5.运行之后预制体确实成功实…

【实例】React 状态管理库 MobX Redux 入门及对比

上一篇&#xff1a;【实例】React 组件传值方法: Props、回调函数、Context、路由传参 MobX MobX 是一个状态管理库&#xff0c;它提供了一种响应式的数据流方案&#xff0c;使得状态的变化能够自动地反映到相关的组件中。 MobX 的核心理念是可观察的状态&#xff08;Observa…

思科无线控制器配置学习

文章目录 简单拓扑WLC配置 简单拓扑 WLC配置 WLC#show running-config Building configuration...Current configuration : 11943 bytes ! ! Last configuration change at 16:22:44 UTC Thu Mar 14 2024 by admin ! version 17.9 service timestamps debug datetime msec se…

鸿蒙一次开发,多端部署(七)响应式布局

自适应布局可以保证窗口尺寸在一定范围内变化时&#xff0c;页面的显示是正常的。但是将窗口尺寸变化较大时&#xff08;如窗口宽度从400vp变化为1000vp&#xff09;&#xff0c;仅仅依靠自适应布局可能出现图片异常放大或页面内容稀疏、留白过多等问题&#xff0c;此时就需要借…

农业四情监测系统的工作原理

农业四情监测系统的工作原理【TH-Q1】农业四情监测系统是一种应用现代科技手段&#xff0c;以实现对农田环境信息的实时监测和数据采集的系统。这一系统通过对农田的土壤、气象、病虫害以及作物生长状况等四个方面的实时监测&#xff0c;帮助农民和农业管理者更好地了解和掌握农…

网络: 传输层

功能: 将数据从发送到传给接收端 UDP 无连接状态: 知道对端的IP和端口号就直接进行传输, 不需要建立连接不可靠: 没有确认机制, 没有重传机制. 出错不会管面向数据包: 不能够灵活的控制读写数据的次数和数量 发送速度快: 立即发送 报文结构 TCP 面向连接可靠 校验和序列号(按…

测试框架到底是什么,如何定义?

测试框架的关键组件是什么&#xff1f; 测试执行引擎&#xff1a;协调测试的运行、管理序列和报告结果。 测试脚本存储库&#xff1a;存储将要执行的实际测试用例或脚本。 测试数据&#xff1a;测试执行所需的输入数据&#xff0c;可以是静态的、动态的或动态生成的。 存根和…

十四届蓝桥杯 冶炼金属(二分 / 公式)

二分代码1&#xff1a; #include<iostream> #include<cstdio> #include<cmath> using namespace std;int get(int a, int b){int l1;r1e91;while(l<r){int mid lr >>1;if(a / mid < b){r mid;}else l mid 1;}return l; } int main() {int n…

【机器学习】基于机器学习的分类算法对比实验

摘要 基于机器学习的分类算法对比实验 本论文旨在对常见的分类算法进行综合比较和评估&#xff0c;并探索它们在机器学习分类领域的应用。实验结果显示&#xff0c;随机森林模型在CIFAR-10数据集上的精确度为0.4654&#xff0c;CatBoost模型为0.4916&#xff0c;XGBoost模型为…

Obsidian+PicGo+Gitee搭建免费图床

之前使用PicGoGitee配合Typora&#xff0c;后来因为换电脑Typora管理笔记不方便&#xff0c;换到Obsidian笔记&#xff0c;此处记录重新搭建图床的坑与经验。 主要参考# picGogitee搭建Obsidian图床&#xff0c;实现高效写作&#xff01; 1 下载安装PicGo 下载链接https://mo…

u盘表格不小心删除怎么恢复数据,u盘误删的表格怎么找回

u盘表格不小心删除怎么恢复数据?当我们使用U盘存储重要数据时,不小心删除文件或者整个表格可能会导致数据的丢失。这种情况下,我们需要采取一些措施来恢复被删除的数据。u盘误删的表格怎么找回?幸运的是,有一些方法可以帮助我们恢复U盘中的数据,即使它们被删除了。在本文…