60天零基础干翻C++————双指针问题

news/2024/5/7 7:53:43

移动零

题目链接:移动零
在这里插入图片描述
本题是典型的双指针算法中的数组划分类型:
以下面为例:在这里插入图片描述
删除该数组所有的0.
下面引入两个指针:
在这里插入图片描述
这两个指针将区间分为了三段
在这里插入图片描述
初始如图 定义两个指针:
在这里插入图片描述
cur会有两种情况:

  1. 遇到非零元素。
  2. 遇到0元素。
    此时为cur第一种情况:我们需要将dest和cur直接的非零元素移动到dest之前。
    在这里插入图片描述
    dest++后,和cur 互换。然后cur++,持续上述过程。当走到下图所示时
    在这里插入图片描述
    cur指向0,则cur++,dest不变

在这里插入图片描述
此时进入cur指向非零元素,cur指向的元素需要移动到dest之前
在这里插入图片描述
持续此流程就可以完成。
下面打印出每次交换流程:

在这里插入图片描述
打印测试代码:

void Swap(int& a,int& b)
{int c = a;a = b;b = c;
}void print(vector<int> x)
{for (int i = 0; i < x.size(); i++){cout <<x.at(i)<<' ';}cout << endl;
}void Movezeroes(vector<int>& k)
{print(k);int cur = 0;int dest = -1;for (cur = 0; cur < k.size(); cur++){if (k[cur] != 0){dest++;Swap(k[cur], k[dest]);print(k);}}
}int main()
{vector<int> a;a.push_back(1);a.push_back(2);a.push_back(0);a.push_back(0);a.push_back(0);a.push_back(2);a.push_back(1);a.push_back(0);a.push_back(1);Movezeroes(a);return 0;}

复写0

题目链接: 复写0
在这里插入图片描述
复写0是典型的双指针算法。刚拿到题目可能被简单迷惑。本题如果从前往后会数据覆盖。从后往前的话双指针又指向哪里呢?我们看下面几个例子:
在这里插入图片描述
可以看出关键就是要找到复写之后的最后一个数。那么如何找出这个复写的数呢?
此时可以看出 可以将数组分成两个区间
在这里插入图片描述

可以看出当0越多,需要的复写空间越。那么我们可以用双指针 用tail统计需要留出多少空间

int head = 0;int tail = arr.size()-1;while(tail>head){if (arr[head] == 0){tail--;}++head;                                                 		}

复写占用空间相当于被抛弃的空间,所以遍历不在扫描。

此时的tail所指向的位置就是红色字,tail指向的位置有三种情况

  1. tail指向0,该0不需要复写,因为后面空间不够。这是最特殊的情况。
  2. tail指向0,需要复写。
  3. tail指向非0.
    此时当tail指向0时,我们如何得知是否需要复写就需要单独讨论呢。
    在这里插入图片描述
    我们发现,需要复写时head走到了tail后面。不需要复写时他们相等。这是什么原因呢

先分析第一种情况,tail和head不相等。
在这里插入图片描述
当head指向的0是离tail最近的一个时,此时分为两种情况:

  1. tail和head指向同一个0;
  2. head指向tail之前的0;
    在这里插入图片描述
    因为复写占用的空间是在head和tail之间,所以可以通过tail-head是否为0判断 是否可以复写。显然第一种可以复写,第二种,复写空间为0,不能复写。所以当head和tail同时指向的0不能复写。这种情况我们提前处理,把0当成普通元素。
int cur = tail;int dest = arr.size();if (head == tail && arr[cur] == 0 ){dest--;arr[dest] = arr[cur];cur--;}

后面就是简单的重后往前的复写操作了。

while (dest > 0){if (arr[cur] == 0){dest--;arr[dest] = 0;}dest--;arr[dest] = arr[cur];cur--;}

快乐数

题目链接:快乐数
在这里插入图片描述

  1. 根据第一条,我们需要得到余数 的平方和,这个是很容易的
int Add(int n)
{int  len = log10(n)+1;int sum = 0;int tmp = 0;for (int i = 1; i < len+1; i++){tmp = n %10;sum = sum + tmp * tmp;n = n / 10;}return sum;
}

在这里插入图片描述
2. 当出现1时 1单独成环。没有1时,其他数成环
我们只要验证,成环之时,有没有1即可
此处使用快慢指针。快指针走两步,慢指针走一步。在环内部,快慢指针一定会相遇。如果相遇是1,则环内只有1,相遇不是1,则环内一定没用1.因为1,是单独成环,

  bool isHappy(int n) {
int slow = 0;int fast = 0;slow = n;fast = Add(n);// 调用一次Add相当于走一步。while (slow != fast){slow = Add(slow);fast = Add(Add(fast));}if (slow==1)// 如果等于1.则环内只有1.{return true;}return false;}

盛最多水的容器

题目链接:盛最多水的容器

在这里插入图片描述
v= len*wide。显然随着左右指针向中间靠拢,wide一直减少。决定v的只有len。而len由左右最小的数决定。
所以,随着wide的减小决定v的关键就是左右最小的数 len。所以在移动时也应该移动最小的,

在这里插入图片描述
图中可以看出,v随着wide变小,最终由min(left,right)决定。所以,最小的移动才能改变v,在wide减少的情况下

  int maxArea(vector<int>& height) {int head = 0;//leftint tail = height.size() - 1;// rightint high = 0;  // min(rigrht,left)int wide = 0;int v = 0;while (tail > head){wide = tail - head;high = min(height[tail], height[head]);v = Max(wide * high, v);//记录体积最大的情况。if (height[tail] > height[head]){head++;}else{tail--;}}return v;}

有效三角形的个数

题目链接:有效三角形的个数
在这里插入图片描述
首选需要三个指针分别表示三条边的数值。为了让指针abc指向不重复,我们可以考虑将数组排序。排序有两个好处:

  1. 只要让一个指针a指向最大值,那么只需要满足较小b c满足b+c>a.
  2. abc 不会重复选择。
    画图说明各个情况 排序完成后
    在这里插入图片描述

分为两大类情况

  1. a+b>c 满足情况,此时调小a+b 左移b
    在这里插入图片描述

  2. a+b<=c 不满足 此时

1.调小a+b 2. 调小c
在这里插入图片描述

  1. 调小a+b
    在这里插入图片描述

  2. 调小c
    在这里插入图片描述
    注意事项:
    在这里插入图片描述

int triangleNumber(vector<int>& nums) {sort(nums.begin(),nums.end());
int head=0;
int Maxtail=nums.size()-1;
int tail=nums.size()-2;
int num=0;
for(Maxtail;Maxtail>1;Maxtail--)
{head=0;tail=Maxtail-1;while(tail>head){if(nums[tail]+nums[head]>nums[Maxtail]){num+=tail-head;tail--;}else{head++;}}
}
return num;}

两数之和

题目链接:两数之和
在这里插入图片描述

对于有序数组,本质还是谁有问题谁走
在这里插入图片描述


http://www.mrgr.cn/p/17736348

相关文章

UE4 寻路

寻路 就是对图的遍历,目前主要处理对可转换为二维矩阵的方格图遍历 DFS 与 BFS 两种最基础的遍历方式,DFS采用回溯思想,将从起点开始沿着一个方向搜索,直到超出界限(回溯)或者到达目的地(返回结果) //只考虑上下左右四个方向 vector<vector<pair{int,int}>> re…

Postman之全局变量与环境变量配置

实际开发中可能需要不停切换环境&#xff0c;接口中来回输入环境地址比较麻烦&#xff0c;故而通过定义变量来节约频繁更换测试地址所耗费的时间。Postman 允许定义自己的全局变量&#xff08;Globals&#xff09;与环境变量&#xff08;Environment&#xff09;&#xff0c;最…

03 OLED显示屏实现

目录前言一、软件模拟IIC协议1.开启IIC协议2.结束IIC协议3.传输数据二、OLED的操作1.传输数据的准备2.写入命令3.写入数据4.初始化函数5.设置光标6.显示字符7.显示字符串8.清屏9.显示汉字10.显示图片11.显示动图三、完整代码总结 前言 这一章主要是上一节没有讲完的项目的一个编…

ETL工具-nifi干货系列 第十七讲 nifi Input PortOut Port 实战教程

1、端口(Port),包含输入端口(Input Port)和输出端口(Out Port ) 使用一个或多个处理组构建的数据流需要一种方式将处理组连接到其他数据流组件。 处理组和处理组之间可以通过使用端口来进行连接。这里的端口和kettle中的步骤【复制记录到结果】、【从结果获取记录】是类…

缓存的使用及常见问题的解决方案

1.什么是缓存 缓存就是数据交换的缓冲区&#xff08;称作Cache&#xff09;&#xff0c;是存储数据的临时地方&#xff0c;一般读写性能较高。 一个web应用中缓存的使用&#xff1a; 用户通过浏览器向我们发送请求&#xff0c;这个时候浏览器就会建立一个缓存&#xff0c;主要…

力扣-119. 杨辉三角 II

1.题目 题目地址(119. 杨辉三角 II - 力扣(LeetCode)) https://leetcode.cn/problems/pascals-triangle-ii/ 题目描述 给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 1: 输入: rowIndex = 3 输…

Flask中的JWT认证构建安全的用户身份验证系统

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Flask中的JWT认证&#xff1a;构建安全的用户身份验证系统 随着Web应用程序的发展&#xf…

17.Nacos与Eureka区别

Nacos会将服务的提供者分为临时实例和非临时实例。默认为临时实例。 临时实例跟eureka一样&#xff0c;会向注册中心报告心跳监测自己是否还活着。如果不正常了nacos会剔除临时实例。&#xff08;捡来的孩子&#xff09; 非临时实例&#xff0c;nacos会主动询问服务提供者是否…

搜维尔科技:【工业仿真】煤矿机械安全事故VR警示教育系统

产品概述 搜维尔科技 煤矿机械安全事故VR警示教育系统 系统内容&#xff1a; 系统采用虚拟现实技术模拟矿井井下机械安全技术及事故&#xff0c;展现井下常见机械伤害事故&#xff0c;表现伤害事故的隐患点&#xff0c;能够模拟事故发生和发展过程&#xff1b;营造井下灾害发…

JVM虚拟机监控及性能调优实战

目录 jvisualvm介绍 1. jvisualvm是JDK自带的可以远程监控内存&#xff0c;跟踪垃圾回收&#xff0c;执行时内存&#xff0c;CPU/线程分析&#xff0c;生成堆快照等的工具。 2. jvisualvm是从JDK1.6开始被继承到JDK中的。jvisualvm使用 jvisualvm监控远程服务器 开启远程监控…

初入数据库

SQL&#xff1a;操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数据库的统一标准。 DDL&#xff08;Data Definition Language&#xff09;数据定义语言 数据库 show databases;create database db01;use db01;select database(); 显示当前使用的数据库drop d…

05、应急事件检测

应急事件检测 1.Windows 系统 1.1.Windows 系统用户账号收集 查找本地用户和组:lusrmgr.msc 查找用户:net user 查找本地管理员组用户:net localgroup administrators 使用 powershell 查找用户:Get-LocalUser 1.2.Windows 系统进程信息收集 任务管理器(Ctrl+Shift+Esc)(…

SEGGER Embedded Studio IDE移植FreeRTOS

SEGGER Embedded Studio IDE移植FreeRTOS 一、简介二、技术路线2.1 获取FreeRTOS源码2.2 将必要的文件复制到工程中2.2.1 移植C文件2.2.2 移植portable文件2.2.3 移植头文件 2.3 创建FreeRTOSConfig.h并进行配置2.3.1 处理中断优先级2.3.2 configASSERT( x )的处理2.3.3 关于系…

mybatis中<if>条件判断带数字的字符串失效问题

文章目录 一、项目背景二、真实错误原因说明三、解决方案3.1针对纯数字的字符串值场景3.2针对单个字符的字符串值场景 四、参考文献 一、项目背景 MySQL数据库使用Mybatis查询拼接select语句中进行<if>条件拼接的时候&#xff0c;发现带数字的或者带单个字母的字符串失效…

md5绕过

md5绕过 ($a != $b && md5($a) == md5($b))的绕过 传参a=s1885207154a,b=s1836677006aMD5值:md5("s1885207154a") => 0e509367213418206700842008763514md5("s1836677006a") => 0e481036490867661113260034900752在PHP中 0e开头表示为科学…

Hadoop——Yarn基础架构

Hadoop——Yarn基础架构 Hadoop YARN&#xff08;Yet Another Resource Negotiator&#xff09;是Apache Hadoop生态系统中的一个子项目&#xff0c;它是用于集群资源管理的框架&#xff0c;负责为运算程序提供服务器运算资源&#xff0c;相当于一个分布式的操作系统平台&…

js的算法-交换排序(冒泡)

交换排序 所谓交换排序&#xff0c;是指根据序列中两个元素关键字的比较结果来对换这两个记录在序列中的位置。基于交换的排序算法很多&#xff0c;本次介绍冒泡排序和快速排序。 冒泡 基本思想 从后往前&#xff08;或从前往后&#xff09;两两比较相邻元素的值&#xff0…

01_Linux最简单驱动-helloworld

Linux最简单驱动-helloworld 驱动分为四个部分: ​ 头文件 ​ 驱动模块的入口和出口 ​ 声明信息 ​ 功能实现 第一步,包含头文件 #include <linux/init.h> 包含宏定义的头文件 #include <linux/module.h> 包含初始化加载模块的头文件 第二步,驱动模块的入口和出…

《QT实用小工具·四十二》圆形发光图像

1、概述 源码放在文章末尾 该项目实现了图像的发光效果&#xff0c;特别适合做头像&#xff0c;项目demo演示如下所示&#xff1a; 项目部分代码如下所示&#xff1a; import QtQuick 2.7 import QtGraphicalEffects 1.12Item {id: rootwidth: 80height: 80property int ra…

Grid 布局

文章目录 容器属性display 属性grid-template-columns 和 grid-template-rows 属性row-gap、column-gap、gap 属性grid-template-areas 属性grid-auto-flow 属性justify-items、align-items、place-items 属性justify-content、align-content、place-content 属性grid-auto-col…