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

【C++算法】双指针

移动零

题目链接:移动零icon-default.png?t=N7T8https://leetcode.cn/problems/move-zeroes/description/

  • 算法原理

这类题是属于数组划分、数组分开题型

  • 代码步骤:
  1. 使用cur遍历数组
  2. 当cur所指的元素等于0时,cur向后面移动
  3. 当cur所指的元素不等于0时,dest向后面移动,cur所指元素与dest移动后所指的元素交换
  4. 当cur指向最后一个元素的下一个时,结束。
  • 代码展示
class Solution {
public:void moveZeroes(vector<int>& nums) {int dest = -1;for(int cur = 0; cur < nums.size(); ++cur){//如果cur所指的元素非0,交换if(nums[cur] != 0){swap(nums[++dest], nums[cur]);}}}
};

复写零

题目链接:

复写零icon-default.png?t=N7T8https://leetcode.cn/problems/duplicate-zeros/description/

  • 算法原理

  • 代码步骤:

  • 代码展示
class Solution {
public:void duplicateZeros(vector<int>& arr) {//寻找复写的最后一个元素int cur = 0;int dest = -1;int n = arr.size();//注意arr.sizr()是size_t无符号类型//int(-1)比size_t整数大while(cur < n){if(arr[cur]){++dest;}else{dest += 2;}//注意这个判断条件需要在里面实现//如果在整个循环结束判断,cur的值无法保证if(dest >= n-1) break;cur++;}//特殊情况处理if(dest == n){arr[n - 1] = 0;--cur;dest -= 2;}//进行从右向左的复写操作for(; cur >= 0; --cur){if(arr[cur]){arr[dest--] = arr[cur];}else{arr[dest--] = 0;arr[dest--] = 0;}}  }
};

快乐数

题目链接:

快乐数icon-default.png?t=N7T8https://leetcode.cn/problems/happy-number/submissions/552733314/

  • 算法原理

  • 代码步骤:

采用快慢双指针的思想:

  1. 定义快慢双指针
  2. 设置一个每个位置平方和的函数
  3. 慢指针每次向后移动一步
  4. 快指针每次向后移动俩步
  5. 判断快慢指针相遇的时候的值是否为1即可
  • 代码展示
class Solution {
public://计算数每个位置上数字的平方和int SquareSum(int n){int sum =0;while(n > 0){int num = n % 10;sum += num * num;n /= 10;}return sum;}bool isHappy(int n) {int slow = n;int fast = SquareSum(n);while(slow != fast){fast = SquareSum(SquareSum(fast));slow = SquareSum(slow);}if(slow == 1){return true;}else {return false;}}
};

盛最多水的容器

题目链接:

盛最多水的容器icon-default.png?t=N7T8https://leetcode.cn/problems/container-with-most-water/

  • 算法原理

  • 代码步骤:
  1. 记录初始w最大时的初始容积
  2. left与right二者中较小者向里面移动,寻找比自己大的值
  3. 找到比自己大的值,记录面积,并与之前的面积比较大小
  4. 当left与right相遇的时候,结束
  • 代码展示
class Solution 
{
public:int maxArea(vector<int>& height) {int left = 0;int right = height.size() - 1;//寻找边界的最小值int min = (height[left] < height[right]) ? height[left] : height[right];//起始容积int vmax = min * (right - left);while(left < right){if(height[left] < height[right]){//记录此时的leftint num = left;while(left < right){//比较看是否有比height[left]大的值++left;if(height[num] < height[left]){break;}}}else{//记录此时的leftint num = right;while(left < right){//比较看是否有比height[left]大的值--right;if(height[num] < height[right]){break;}}}min = (height[left] < height[right]) ? height[left] : height[right];int v = min * (right - left);vmax = (v > vmax) ? v : vmax; }return vmax;}
};
class Solution {
public:int maxArea(vector<int>& height) {int left = 0, right = height.size() - 1, vmax = 0;while(left < right){int v = min(height[left], height[right]) * (right - left);vmax = max(vmax, v);if(height[left] < height[right]) ++left;else --right;}return vmax;}
};

有效三角形个数

题目链接:

有效三角形个数icon-default.png?t=N7T8https://leetcode.cn/problems/valid-triangle-number/

  • 算法原理

  • 代码步骤:
  1. 对数组进行排序
  2. 设置三个指针,一个指向最大值,另外俩个形成单调双指针
  3. 当left + right < max时,个数为right-left,right--
  4. 当left + right >= max时,个数为0,left++
  • 代码展示
class Solution {
public:int triangleNumber(vector<int>& nums) {int n = nums.size();//排序升序sort(nums.begin(), nums.end());int sum = 0;//最大值向前移动while(n >= 2)//确保right不越界{int max = nums[n - 1];int left = 0, right = n - 2;//利用单调性使用双指针while(left < right){if(nums[left] + nums[right] > max){sum += (right - left);right--;}else{left++;}}--n;}return sum;}
};

三数之和

题目链接:

三数之后icon-default.png?t=N7T8https://leetcode.cn/problems/3sum/

  • 算法原理

  • 代码步骤:
  1. 排序
  2. 固定一个数min(注意当min > 0的时候,也是可以直接结束的)
  3. 在该数的后面的区间之内,利用单调性使用双指针,快速找到俩个和等于-min的值
  4. 细节1:不漏数据
  5. 细节2:去重操作
  • 代码展示
class Solution 
{
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> vv;//排序sort(nums.begin(), nums.end());int n = nums.size();//固定一个数int min = 0;for(int min = 0; min < n - 2; ++min){//优化if(nums[min] > 0) break;int left = min + 1, right = n - 1;while(left < right){if(nums[left] + nums[right] < -nums[min]){left++;}else if(nums[left] + nums[right] > -nums[min]){right--;}else{//添加数据vv.push_back({nums[min], nums[left], nums[right]});while(left < right && nums[left] == nums[left + 1]){left++;}while(left < right && nums[right] == nums[right - 1]){right--;}if(left < right){left++;right--;}}}while(min < n - 2 && nums[min] == nums[min + 1]){min++;}}return vv;}
};

四数之和

题目链接:

四数之和icon-default.png?t=N7T8https://leetcode.cn/problems/4sum/description/

  • 算法原理

  • 代码步骤:

  • 代码展示
class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ret;//排序sort(nums.begin(), nums.end());int n = nums.size();//四数之和for(int minA = 0; minA < n;){long targetA = target - nums[minA];//三数之和for(int minB = minA + 1; minB < n;){long targetB = targetA - nums[minB];int left = minB + 1, right = n - 1;while(left < right){//利用单调性使用双指针if(nums[left] + nums[right] < targetB){left++;}else if(nums[left] + nums[right] > targetB){right--;}else{ret.push_back({nums[minA], nums[minB], nums[left], nums[right]});//left不重while(left + 1 < right && nums[left] == nums[left + 1]){left++;}//right不重while(left < right - 1 && nums[right] == nums[right - 1]){right--;}//不漏if(left < right){left++;right--;}}}//minB不重while(minB + 1 < n && nums[minB] == nums[minB + 1]){minB++;}++minB;}//minA不重while(minA + 1 < n && nums[minA] == nums[minA + 1]){minA++;}++minA;}return ret;}
};  

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 45.跳跃游戏
  • 爬虫练习_01
  • 代码随想录算法day16 | 二叉树part06 | 654.最大二叉树,617.合并二叉树,700.二叉搜索树中的搜索,98.验证二叉搜索树
  • 做报表用什么工具?不想再用Excel了!!!
  • Tomcat漏洞
  • Python配置文件格式——INI、JSON、YAML、XML、TOML
  • golang使用channel实现读写锁
  • Qt使用lupdate工具生成.ts文件
  • DevOps环境搭建
  • Python | Leetcode Python题解之第326题3的幂
  • STM32 标准库移值RTThread
  • LeetCode226 翻转二叉树
  • 学习方法[1]:如何摆脱无知?(致尚未放弃学习的人)
  • Allegro如何更改过孔的网络
  • NoSQL 详细讲解
  • [nginx文档翻译系列] 控制nginx
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • Gradle 5.0 正式版发布
  • LeetCode18.四数之和 JavaScript
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • mysql中InnoDB引擎中页的概念
  • PHP CLI应用的调试原理
  • Python 基础起步 (十) 什么叫函数?
  • 当SetTimeout遇到了字符串
  • 多线程 start 和 run 方法到底有什么区别?
  • 区块链将重新定义世界
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 突破自己的技术思维
  • 优秀架构师必须掌握的架构思维
  • 主流的CSS水平和垂直居中技术大全
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • # 利刃出鞘_Tomcat 核心原理解析(七)
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #git 撤消对文件的更改
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • #QT(串口助手-界面)
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (12)目标检测_SSD基于pytorch搭建代码
  • (2)STM32单片机上位机
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (arch)linux 转换文件编码格式
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (安卓)跳转应用市场APP详情页的方式
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (十七)Flink 容错机制
  • (实测可用)(3)Git的使用——RT Thread Stdio添加的软件包,github与gitee冲突造成无法上传文件到gitee
  • (一)基于IDEA的JAVA基础1
  • (译) 函数式 JS #1:简介
  • (转) 深度模型优化性能 调参
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复