当前位置: 首页 > news >正文

C/C++精品算法——双指针(1) - 实践

C/C++精品算法——双指针(1) - 实践

文章目录

  • 一、前言
  • 二、双指针的定义
  • 三、手撕算法题
    • 3.1 移动零
    • 3.2 复写零
    • 3.3 快乐树
    • 3.4 盛最多水的容器
  • 四、总结

一、前言

编程如同球场,唯有自己不断突破,才能取得最后的胜利
鑫-萍的个人主页
鑫-萍的Gittee仓库
人生名言——与其被动迎敌,不如主动出击在这里插入图片描述

Hello,各位热爱编程的小伙伴们!今天的你们是否充实呢?鲁迅曾今说过——必须如蜜蜂一样,采过许多花,这才能酿出蜜来。在生活中,我们又何尝不是这样呢,唯有努力向前,才能不负韶华。好啦,划归主题,今天我要跟大家分享的内容是:C/C++精品算法——双指针。

二、双指针的定义

大家听到双指针这个名词的时候,可能大脑一片空白,双指针又是什么?从来没有听说过啊?这里,就由up来给大家进行讲解。

双指针算法是 C/C++ 中一种高效的线性 / 近线性时间复杂度算法思想,核心是通过维护两个指针(索引 / 迭代器),在遍历数据结构(如数组、链表、字符串)时协同移动,替代传统的嵌套循环,从而将时间复杂度从 O (n²) 优化到 O (n) 或 O (nlog n),同时保持空间复杂度为 O (1)

想必大家在看完双指针的定义,在结合之前C语言和数据结构的知识,大差不差都能理解到大致的意思了吧?不过老话说得好,光看不练假把式,下面呢我给大家分享几道优质算法题,来帮助大家进一步理解双指针。

三、手撕算法题

3.1 移动零

移动零力扣链接
在这里插入图片描述

第一题,就先给大家一道相对简单的算法题,怎么样,在扫视完此题之后,你是否有了解题思路了呢?没有的话也没关系,请仔细观看up的解题思路再加以理解。
画图展示:

在这里插入图片描述
在这里插入图片描述

具体思路:

先定义两个变量,cur和des,让cur指向数组的第一个元素,des指向数组第一个元素的前一个元素。如果cur指向的元素为0,就让cur++指向下一个元素,如果cur指向的元素非0,就先让des++指向下一个元素,再交换cur和des所指向的元素,以此循环,直到cur超出整个数组元素个数时跳出循环。

代码展示:

在这里插入图片描述

class Solution {
public:
void moveZeroes(vector<int>& nums) {int cur = 0,des = -1;int n = nums.size();while(cur<n){if(!nums[cur]) cur++;//为0,cur++else swap(nums[cur++],nums[++des]);//非0,先让des++,再交换cur和des所指向的元素,再让cur++//     if(nums[cur]) swap(nums[cur],nums[++des]);//    cur++;}}};

3.2 复写零

怎么样,第一道题可谓是小试牛刀,先让大家熟悉熟悉,现在再让我们来看第二题。

复写零力扣链接
在这里插入图片描述

大家这时可以先暂停一下,整理整理自己的思路,再实现一下代码,稍微多花一些时间去解决这道题,如果确实做不出来,再来返回看up的解题思路。
画图展示:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

具体思路:

先定义两个变量cur和des,让cur指向数组的第一个元素,让des指向数组第一个元素的前一个元素。
第一步:当cur所指向元素没有超出数组个数时,如果cur指向元素非0,就让des++走一步,如果cur指向的元素为0,就让des+=2走两步,如果des>=n-1就结束循环。
第二步:若此时des=n-1,cur所指向的元素就是要复写的最后一个元素;若此时des=n,让arr[n-1]=0,然后让cur–后退一步,des-=2后退两步,现在cur指向的元素就是要复写的最后一个元素。
第三步:从后往前复写,如果cur所指向元素非0,就交换cur和des所指向的元素,再让cur–和des–;如果cur所指向元素为0,就让des所指向的元素为0,让des–,然后再让des所指向的元素为0,再让cur–,des–。重复以上步骤,直到不满足cur>0这个循环条件时跳出循环。

代码展示:

在这里插入图片描述

class Solution {
public:
void duplicateZeros(vector<int>& arr) {int cur = 0,des = -1;int n = arr.size();while(cur<n)//找到也复写的最后一个元素{if(arr[cur]) des++;else des+=2;if(des>=n-1) break;cur++;}while(des==n)//判断临界情况{arr[n-1] = 0;cur--;des-=2;}while(cur>0)//从后往前进行复写{if(arr[cur]) swap(arr[cur--],arr[des--]);else{arr[des--] = 0;arr[des]=0;des--;cur--;}}}};

怎么样?这第二题你是否独立做对了呢?不知道大家有这样的一种感觉没有,这第二题明显比第一题难了不少,不过即使你没有独立的做出来也不要灰心,因为此题确实不简单哦。让我们整装待发,再来看第三题。

3.3 快乐树

快乐数力扣链接
在这里插入图片描述

画图展示:

在这里插入图片描述

在这里插入图片描述

具体思路:

定义快慢指针——slow和fast,slow每次走一步,fast每次走两步,若slow和fast可以相遇且都为1时,证明此数为快乐数。

代码展示:

在这里插入图片描述

class Solution {
public:
int Addition(int n)//求各位数的平方和
{
int ret = 0;
int tmp = 0;
while(n)
{
tmp = n % 10;
ret+=pow(tmp,2);
n = n / 10;
}
return ret;
}
bool isHappy(int n) {
int slow = n,fast = n;//定义快慢指针
while(1)
{
slow = Addition(slow);//slow每次走一步
fast =Addition( Addition(fast));//fast每次走两步
if(slow==fast)
{
return slow==1;//相等且都为1,符合快乐数定义
}
}
//下面注释为解法二
// int slow = n,fast = Addition(n);
// while(slow!=fast)
// {
//      slow = Addition(slow);
//      fast =Addition( Addition(fast));
// }
// return slow == 1;
}
};

3.4 盛最多水的容器

盛最多水的容器力扣链接
在这里插入图片描述

画图展示:

在这里插入图片描述

在这里插入图片描述
由上图可知,能围成的最大容积即为30

具体思路:

定义两个变量left与right,让left指向数组的第一个元素,right指向数组的最后一个元素,算出能围成的容积,然后让小的那个变量进行移动,若两个变量所指向的数值的相等,就让任意一个变量移动,按照以上进行循环,直到不满足left<right这个循环条件时,跳出循环,最后找出最大的容积即可。

代码展示:

在这里插入图片描述

class Solution {
public:
int maxArea(vector<int>& height) {int n = height.size();int left = 0, right = n - 1;int area = 0;while (left < right)//进入循环{if (height[left] < height[right])//左小{area = max(area, (right - left) * height[left]);left++;}else if (height[left] > height[right])//右小{area = max(area, (right - left) * height[right]);right--;}else {//相等area = max(area, (right - left) * height[right]);if (height[left + 1] < height[right - 1])  left++;else right--;// if (height[left + 1] > height[right - 1])  right--;// else left++;}}return area;}};

四、总结

怎么样,经过这四题的锤炼,你是否已经对双指针算法一定程度上地掌握了呢?总的来说,这四题相对比较简单,所以大家还是要独立地去思考和解题。学习算法的道路上,总是充满坎坷,但是只要我们努力,这些算法题总会被我们理解透彻,可谓是——刷题百遍,其意自现。

http://www.gsyq.cn/news/116326.html

相关文章:

  • 2025济宁婚纱摄影店推荐星级排名及甄选指南 - 提酒换清欢
  • Windows便携版Postman终极指南:打造高效移动开发环境
  • Java方法调用链分析:深度掌握代码执行路径的完整指南
  • 2025 BI本地私有化部署厂商新锐盘点:大模型+自然语言看板重塑数据决策服务商集锦 - 品牌2026
  • 5分钟快速上手:Pyecharts数据可视化从入门到精通
  • 2025年物业安保公司权威推荐榜单:现场安保公司/随身护卫公司/安保培训公司服务供应商精选 - 品牌推荐官
  • 模型分支与拼接
  • 如何快速掌握Python动态进度条:alive-progress终极指南
  • 百度网盘秒传工具完整使用教程:快速掌握文件转存技巧
  • 三值逻辑
  • 2025年四川臭虫防治服务渠道权威推荐榜单:成都臭虫灭治服务/四川上门除臭虫公司/四川臭虫治理供应商精选 - 品牌推荐官
  • 为什么你的数据治理效果难固化?关键在这2个核心动作
  • 合同管理软件选型:五款主流平台功能与场景适配分析 - 品牌排行榜
  • 【企业级Docker更新实战指南】:Agent服务无缝升级的5大黄金步骤
  • 2025干洗店加盟优质品牌推荐榜-低风险高支持创业指南 - 资讯焦点
  • AMD 780M APU性能大爆发:ROCm优化库深度配置指南
  • 深入解析:3步解决iOS数据库灾难:GRDB.swift文件修复全指南
  • 2025年移动悬臂吊机定制厂家权威推荐榜单:克令吊机/小型船用吊机/港口码头移动吊机制造商精选 - 品牌推荐官
  • 鸿蒙远程真机终极指南:HOScrcpy让调试变得像玩游戏一样简单
  • 不只是朗读:EmotiVoice让机器学会‘有感情地说话’
  • 【爆】从多模态到全模态:AI大模型革命性进化,编程小白也能看懂的AGI实现路径
  • pytorch nn.Parameter self.register_parameter() 区别
  • 淘宝扭蛋机小程序:开启线上娱乐与购物的全新融合时代
  • 量子电路设计必知的7大导出格式(专家级可视化指南)
  • ComfyUI-MultiGPU:突破显存限制的分布式计算终极解决方案
  • 【运维自动化-标准运维】如何创建条件分支流程
  • 告别手写布局:Tkinter可视化拖拽工具如何让Python GUI开发提速10倍
  • 2025年长沙口腔医院 / 门诊怎么选?5 家权威机构实测推荐,性价比 + 诊疗效果双优 - 博客万
  • JavaScript DOM 原生部分(五):事件绑定
  • 30分钟速成!本地部署大模型全攻略:从零开始打造自定义AI助手!