刷题训练之双指针问题

2024-01-06 17:12

本文主要是介绍刷题训练之双指针问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

> 作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等
> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:熟练掌握双指针,并且能把下面的题目做出

> 毒鸡汤:人生就像一场马拉松比赛,不是看谁跑得最快,而是看谁坚持到最后。

> 望小伙伴们点赞👍收藏✨加关注哟💕💕 

🌟前言分析

        最早博主续写了牛客网130道题,这块的刷题是让同学们快速进入C语言,而我们学习c++已经有一段时间了,知识储备已经足够了但缺少了实战,面对这块短板博主续写刷题训练,针对性学习,把相似的题目归类,系统的刷题,而我们刷题的官网可以参考:​​​​​​

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

而今天我们的板块是双指针问题。

⭐知识讲解

双指针有两种形式,一种是对撞指针,另一种是左右指针(快慢指针)。

对撞指针:

  • 对撞指针从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼近。
  • 对撞指针的终⽌条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循 环)

快慢指针:

  • 在一次循环中,每次让慢的指针向后移动一位,而快的指针往后移动两位,实现一快一慢。

⭐经典题型

🌙topic-->1

题目原型:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目分析:

题目说的是,把一个数组含有0的数字甩到数组末尾,但不改变原数组顺序。

讲解算法原理:


编写代码:

class Solution {
public:void moveZeroes(vector<int>& nums) {//两个指针int cur = 0;int dest = -1;for(int i = 0;i < nums.size();i++){//如果遇到0就交换if(nums[cur] != 0){swap(nums[++dest],nums[cur]);}//cur加加cur++;}}
};

 🌙topic-->2

题目原型:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目分析:

题目说,数组有0就再复写一遍,但是不能超过数组原来的长度。

讲解算法原理:

编写代码:

class Solution {
public:void duplicateZeros(vector<int>& arr) {// 求出数组元素个数int n = arr.size();int top = 0;int i = -1;// 入栈while(top < n){i++;if(arr[i] == 0){top = top + 2;}else{top++;}}// 处理边界情况int j = n - 1;if(top == n + 1){arr[j] = 0;j--;i--;}// 开始出栈while(j >= 0){arr[j] = arr[i];j--;// 如果i下标为0就让j再赋值一遍if(arr[i] == 0){arr[j] = arr[i];j--;}i--;}}
};

 🌙topic-->3

题目原型:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目分析:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

讲解算法原理:

编写代码:

class Solution {
public:// 返回每一次剥离的结果int bitSquareSum(int n){int sum = 0;while(n > 0){int t = n % 10; sum = sum + t*t;n = n / 10;}return sum;}bool isHappy(int n) {// 定义两个快慢指针int fast = bitSquareSum(n);int slow = n;// 让快指针走2步,慢指针走1步while(fast != slow){fast = bitSquareSum(bitSquareSum(fast));slow = bitSquareSum(slow);}return slow == 1;}};

🌙topic-->4

题目原型:. - 力扣(LeetCode)

题目分析:

求容量的最大能存水,用最小的柱高(y)乘以容量的宽(x)。

讲解算法原理:


编写代码:

class Solution {
public:int maxArea(vector<int>& height) {// 定义左右指针int left = 0;int right = height.size() - 1;// 定义最大容量vint ret = 0;// 开始循环while(left < right){int v = min(height[left],height[right]) * (right - left);ret = max(v,ret);// 判断指针的移动if(height[left] < height[right]){left++;}else{right--;}}return ret;}
};

 🌙topic-->5

题目原型:. - 力扣(LeetCode)

题目分析:

在数组中找三个数看看有多少个可以组成三角形。

讲解算法原理:

编写代码:

class Solution {
public:int triangleNumber(vector<int>& nums) {// 先让数组排升序sort(nums.begin(),nums.end());// 利用双指针来解决问题int count = 0;int n = nums.size();for(int i = n - 1;i >=2;i--)// 固定最大值{// 定义双指针int left = 0;int right = i - 1;while(left < right){if(nums[left] + nums[right] > nums[i]){count = count + right - left;right--;}else{left++;}}}return count;}
};

 🌙topic-->6

题目原型:. - 力扣(LeetCode)

题目分析:

在数组中找两个数之和能等于target就返回这两个数。

讲解算法原理:

编写代码:

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++;elsereturn {price[left],price[right]};}// 如果没有的话就返回空return {};}
};

🌙topic-->7

题目原型:. - 力扣(LeetCode)

题目分析:

在数组中找三个数之和是否为0,如果为0就返回这三个数,并且不能重复。

讲解算法原理:


编写代码:

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {// 定义数组vector<vector<int>> ret;// 让数组升序sort(nums.begin(),nums.end());int n = nums.size();// 定住一个数字,利用双指针法for(int i = 0;i < n;){// 优化if(nums[i] > 0)break;// 定义双指针int left = i + 1;int right = n - 1;// 标记int target = -nums[i];while(left < right){int sum = nums[left] + nums[right];if(sum > target)right--;else if(sum < target)left++;else{// 尾插ret.push_back({nums[i],nums[left],nums[right]});right--,left++;// 去重left和rightwhile(left < right && nums[left] == nums[left-1])left++;while(left < right && nums[right] == nums[right+1])right--;                   }}// 去重Ii++;while(i < n && nums[i] == nums[i-1])i++;}return ret;}
};

 🌙topic-->8

题目原型:. - 力扣(LeetCode)

题目分析:

在数组中找四个数之和是否为0,如果为0就返回这四个数,并且不能重复。

讲解算法原理:

这里就不讲解原理了,这里和第 7 道题相似的。

编写代码:

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 i = 0;i < n;){// 使用三数之和的方法for(int j = i + 1;j < n;){// 定义双指针int left = j + 1;int 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--]});// 去重leftwhile(left < right && nums[left] == nums[left - 1])left++;while(left < right && nums[right] == nums[right + 1])right--;}}j++;// 去重jwhile(j < n && nums[j] == nums[j - 1])j++;}i++;// 去重iwhile(i < n && nums[i] == nums[i - 1])i++;}return ret;}
};

 🌟结束语

       今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。

这篇关于刷题训练之双指针问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/577027

相关文章

linux生产者,消费者问题

pthread_cond_wait() :用于阻塞当前线程,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast来唤醒它。 pthread_cond_wait() 必须与pthread_mutex 配套使用。pthread_cond_wait()函数一进入wait状态就会自动release mutex。当其他线程通过pthread

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

2024.6.24 IDEA中文乱码问题(服务器 控制台 TOMcat)实测已解决

1.问题产生原因: 1.文件编码不一致:如果文件的编码方式与IDEA设置的编码方式不一致,就会产生乱码。确保文件和IDEA使用相同的编码,通常是UTF-8。2.IDEA设置问题:检查IDEA的全局编码设置和项目编码设置是否正确。3.终端或控制台编码问题:如果你在终端或控制台看到乱码,可能是终端的编码设置问题。确保终端使用的是支持你的文件的编码方式。 2.解决方案: 1.File -> S

vcpkg安装opencv中的特殊问题记录(无法找到opencv_corexd.dll)

我是按照网上的vcpkg安装opencv方法进行的(比如这篇:从0开始在visual studio上安装opencv(超详细,针对小白)),但是中间出现了一些别人没有遇到的问题,虽然原因没有找到,但是本人给出一些暂时的解决办法: 问题1: 我在安装库命令行使用的是 .\vcpkg.exe install opencv 我的电脑是x64,vcpkg在这条命令后默认下载的也是opencv2:x6

问题-windows-VPN不正确关闭导致网页打不开

为什么会发生这类事情呢? 主要原因是关机之前vpn没有关掉导致的。 至于为什么没关掉vpn会导致网页打不开,我猜测是因为vpn建立的链接没被更改。 正确关掉vpn的时候,会把ip链接断掉,如果你不正确关掉,ip链接没有断掉,此时你vpn又是没启动的,没有域名解析,所以就打不开网站。 你可以在打不开网页的时候,把vpn打开,你会发现网络又可以登录了。 方法一 注意:方法一虽然方便,但是可能会有

vue同页面多路由懒加载-及可能存在问题的解决方式

先上图,再解释 图一是多路由页面,图二是路由文件。从图一可以看出每个router-view对应的name都不一样。从图二可以看出层路由对应的组件加载方式要跟图一中的name相对应,并且图二的路由层在跟图一对应的页面中要加上components层,多一个s结尾,里面的的方法名就是图一路由的name值,里面还可以照样用懒加载的方式。 页面上其他的路由在路由文件中也跟图二是一样的写法。 附送可能存在

vue+elementui--$message提示框被dialog遮罩层挡住问题解决

最近碰到一个先执行this.$message提示内容,然后接着弹出dialog带遮罩层弹框。那么问题来了,message提示框会默认被dialog遮罩层挡住,现在就是要解决这个问题。 由于都是弹框,问题肯定是出在z-index比重问题。由于用$message方式是写在js中而不是写在html中所以不是很好直接去改样式。 不过好在message组件中提供了customClass 属性,我们可以利用

Visual Studio中,MSBUild版本问题

假如项目规定了MSBUild版本,那么在安装完Visual Studio后,假如带的MSBUild版本与项目要求的版本不符合要求,那么可以把需要的MSBUild添加到系统中,然后即可使用。步骤如下:            假如项目需要使用V12的MSBUild,而安装的Visual Studio带的MSBUild版本为V14。 ①到MSDN下载V12 MSBUild包,把V12包解压到目录(

YOLO v3 训练速度慢的问题

一天一夜出了两个模型,仅仅迭代了200次   原因:编译之前没有将Makefile 文件里的GPU设置为1,编译的是CPU版本,必须训练慢   解决方案: make clean  vim Makefile make   再次训练 速度快了,5分钟迭代了500次

C语言入门系列:探秘二级指针与多级指针的奇妙世界

文章目录 一,指针的回忆杀1,指针的概念2,指针的声明和赋值3,指针的使用3.1 直接给指针变量赋值3.2 通过*运算符读写指针指向的内存3.2.1 读3.2.2 写 二,二级指针详解1,定义2,示例说明3,二级指针与一级指针、普通变量的关系3.1,与一级指针的关系3.2,与普通变量的关系,示例说明 4,二级指针的常见用途5,二级指针扩展到多级指针 小结 C语言的学习之旅中,二级