我要成为算法高手-双指针篇
目录
- 什么是双指针?
- 问题1:移动零
- 问题2:复写零
- 问题3:快乐数
- 问题4:盛最多水的容器
- 问题5:有效三角形个数
- 问题6:查找总价格和为目标值的两个商品(两数之和)
- 问题7:三数之和
- 问题8:四数之和
- 总结
什么是双指针?
双指针算法是一种常见的解决问题的技巧,通常使用两个变量在链表或者数组中进行迭代、遍历,从而达到解决问题的目的。光说理论太抽象,我们来几道题目吧~~
问题1:移动零
力扣链接:移动零
分析一下题目要求: 将给定数组中所有的0移动到数组的末尾,也就是将数组分成两个区域,前半部分是非零元素,后半部分都是零,并且保持非零元素的相对顺序,如示例1,非零元素的顺序:1,3,12,处理之后非零元素的顺序也要是1,3,12,
解题思路:
既然是双指针算法,那我们就定义两个"指针"咯,这里的"指针",我们是指数组下标
定义两个"指针",dest,cur,
dest:已经处理好的区间内,非0元素的最后一个位置
cur:从左往右遍历数组
dest初始为-1,表示刚开始还没非0元素,cur初始为0
在扫描的过程中,一直让数组保持下面这个状态就好了
图解:
代码实现:
public void moveZeroes(int[] nums) {//双指针:定义dest和cur,dest初始值为-1//dest的作用:非0元素的最后一个位置,也就是[0,dest]的区间是非0元素//cur的作用:从左往右扫描数组,遍历数组int dest = -1;for (int cur = 0; cur < nums.length; cur++) {if (nums[cur] != 0) {//cur遇到非0元素,先交换dest+1位置和cur位置的元素,再dest++,cur++int tmp = nums[dest + 1];nums[dest + 1] = nums[cur];nums[cur] = tmp; dest++;}}
}
问题2:复写零
力扣链接:复写零
分析一下题目要求: 所谓复写,也就是让我们抄一遍数组的内容,遇到非零的直接抄这个数,遇到零抄两遍零,题目要求我们在原数组上进行操作,也就是说不能重新开辟一个新的数组
解题思路:
先找到最后一个需要被复写的数,然后从后往前进行复写,如果从前往后,后面的数会被覆盖掉。
如何找到最后一个被复写的数?还是利用双指针算法,如图
根据cur位置的值,判断dest向前走一步还是两步,走完判断dest是否到达结束位置(dest是否>=arr.length-1),如果dest没有到达结束位置,则让cur++。重复上面的步骤,当dest到达最后位置时,cur指向的就是最后一个被复写的数,要注意的是,dest的位置可能是arr.length-1,也可能是arr.length,如果dest=arr.length(如下图),需要处理这个边界问题,
处理办法:arr[arr.length - 1] = 0;dest -= 2;cur- -;
接下来就可以从后往前开始复写了,拿下图举例
代码实现:
public void duplicateZeros(int[] arr) {int cur = 0;//指向最后一个位置int dest = -1;//dest指结果中,最后需要复写的位置,开始时不知道dest在哪,所以-1//先找到最后一个被复写的数while (cur < arr.length) {if (arr[cur] == 0) {dest += 2;} else {dest++;}if (dest >= arr.length - 1) {break;}cur++;}//边界情况,可能出现:最后要复写两个0,第二个0在arr.length这个位置if (dest == arr.length) {arr[arr.length - 1] = 0;dest -= 2;cur--;}while (cur >= 0) {if (arr[cur] != 0) {arr[dest] = arr[cur];dest--;} else {arr[dest--] = 0;arr[dest--] = 0;}cur--;}}
问题3:快乐数
力扣链接:快乐数
题目要求:题目让我们判断给定的数是不是快乐数,快乐数:每次都对这个数进行一次操作(让它的值替换为它每一位的数的平方之和),重复这个操作,判断最终结果是不是变成1或者无限循环变不到1
解题思路:有点类似之前写过的判断链表是否成环,题目说明了结果是1或者无限循环,但是其实1也是无限循环,1重复上述操作结果永远都是1,所以我们可以使用快慢指针的思想,当两个指针相遇时,判断两个指针指向的数是不是1即可(如果不熟悉判断链表是否成环,可以看这篇哦链表OJ)
代码实现:
//返回n的每一位的平方之和
public int func(int n) {int sum = 0;while (n != 0) {int t = n % 10;sum += t * t;n /= 10;}return sum;
}public boolean isHappy(int n) {int fast = func(n);int slow = n;while (fast != slow) {slow = func(slow);fast = func(func(fast));}return fast == 1;
}
问题4:盛最多水的容器
力扣链接:盛最多水的容器
题目要求: 给定了n条垂线,题目要找出两条线,与X轴构成的容器最多能盛水的容积
解题思路: 容积V = h*w,其中,h指高度,也就是两条线的最短的那条,w指宽度
如图:
代码实现
public int maxArea(int[] height) {//根据规律:向内枚举时,要么宽度肯定减小,但是高度只能是不变或减小(木桶效应)int left = 0;int right = height.length - 1;int maxV = 0;int V = 0;while (left < right) {V = (right - left) * Math.min(height[left], height[right]);if (V > maxV) {maxV = V;}//让高度小的移动,高度小也叫说明容积小,不符合要求if (height[left] <= height[right]) {left++;} else {right--;}}return maxV;
}
问题5:有效三角形个数
力扣链接:有效三角形个数
题目要求:
给定非负整数数组,在数组中挑3个能组成三角形数,求有几种挑法
解题思路:
代码实现:
public int triangleNumber(int[] nums) {// 利用单调性,使用双指针算法int count = 0;int[] ret = nums;Arrays.sort(ret);// 先排个序int flg = ret.length - 1;//固定好flg,表示最大的数while (flg >= 2) {//固定好flg之后,再利用双指针int left = 0;int right = flg - 1;while (left < right) {if (ret[left] + ret[right] > ret[flg]) {count += (right - left);right--;} else {left++;}}flg--;}return count;}
问题6:查找总价格和为目标值的两个商品(两数之和)
力扣链接:查找总价格和为目标值的两个商品
题目要求: 给定数组和target(题目说明了已经排好序了),求数组中和为target的两个数,以数组的形式返回这两个数即可
解题思路: 定义双指针left,right分别指向第一个和最后一个元素,求两个指针指向的元素之和如果小于target,说明,要大一点!让left++,同理如果大于target,说明要小一点~~,让right–,当两个值等于target,此时可以返回了
代码实现:
public int[] twoSum(int[] price, int target) {int[] ret = new int[2];//返回的数组//定义双指针left,rightint left = 0;int right = price.length - 1;while (left < right) {int sum = price[left] + price[right];if (sum < target) {left++;} else if (sum > target) {right--;} else {ret[0] = price[left];ret[1] = price[right];break;}}return ret;}
问题7:三数之和
力扣链接:三数之和
题目要求:
给定整数数组,判断是否存在相加和为0的三个数,这三个数的下标不能重复,也就是说这三个数下标是不一样的,返回所有的三元组,答案不能是重复的三元组
解题思路:
找到之后left和right继续移动,解决了不漏的问题,能够把所有的三元组都找出来,但是并没有满足题目要求:不能重复,解决办法就是:当找到两个数后,记录left和right的值,left和right跳过重复的数,另外,固定的数a(下标是flg)也要跳过重复的数
代码实现:
public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);//先排序int flg = 0;//固定一个的数List<List<Integer>> ret = new ArrayList<>();// 返回的Listwhile (flg <= nums.length-2) {//双指针算法,left,rightint left = flg + 1;//左指针int right = nums.length - 1;//右指针int a = nums[flg];//双指针找目标值和为-a的两个数if(a>0) {//小优化,大于0了,后面的都是>0的数,肯定找不到-abreak;}//双指针算法,思路和求两数之和一样while (left < right) {if (nums[left] + nums[right] < (-a)) {left++;} else if (nums[left] + nums[right] > (-a)) {right--;} else {List<Integer> list = new ArrayList<>();list.add(a);list.add(nums[left]);list.add(nums[right]);ret.add(list);//// 找到结果之后,left,right跳过重复元素,避免越界int leftNumber = nums[left];int rightNumber = nums[right];while (nums[left] == leftNumber && left < nums.length - 1) {left++;}while (nums[right] == rightNumber && right > 0) {right--;}}}// flg也要跳过重复的元素,flg不能越界while (nums[flg] == a&&(flg <= nums.length-2)) {flg++;}}return ret;}
问题8:四数之和
力扣链接:四数之和
题目要求:
在给定数组中,找出4个和为target的数,这四个数的下标不能重复
解题思路:
明白了两数之和跟三数之和后,四数之和的思路就很简单了,先排序,固定一个数a(最左边或者最右边的数,都是一样的),然后在后面的区间按照三数之和的思路:固定一个数b,按照两数之和找出和为target-a-b的两个数
同样的,left、right、flg1、flg2也要跳过重复的数
代码实现:
public List<List<Integer>> fourSum(int[] nums, int target) {Arrays.sort(nums);List<List<Integer>> ret = new ArrayList<>();// 返回的Listfor (int i = 0; i < nums.length; ) {//固定数afor (int j = i + 1; j < nums.length; ) {//固定数bint left = j + 1;int right = nums.length - 1;long aim = (long) target - (nums[i] + nums[j]);//a+bwhile (left < right) {if (nums[left] + nums[right] < aim) {left++;} else if (nums[left] + nums[right] > aim) {right--;} else {List<Integer> list = new ArrayList<>();list.add(nums[left]);list.add(nums[right]);list.add(nums[i]);list.add(nums[j]);ret.add(list);//处理细节,去重int leftNumber = nums[left];int rightNumber = nums[right];while (nums[left] == leftNumber && left < nums.length - 1) {left++;}while (nums[right] == rightNumber && right > 0) {right--;}}}j++;while ((j < nums.length - 2) && nums[j - 1] == nums[j]) {j++;}}i++;while ((i < nums.length - 3) && nums[i - 1] == nums[i]) {i++;}}return ret;
总结
遇到数组划分问题(按要求将数组分划分几个区域)或者如果数组存在单调性(有序的)时,我们可以考虑双指针算法~~
相关文章:
我要成为算法高手-双指针篇
目录 什么是双指针?问题1:移动零问题2:复写零问题3:快乐数问题4:盛最多水的容器问题5:有效三角形个数问题6:查找总价格和为目标值的两个商品(两数之和)问题7:三数之和问题8:四数之和…...
Fake news detection: A survey of graph neural network methods
abstract 各种社交网络的出现产生了大量的数据。捕获、区分和过滤真假新闻的有效方法变得越来越重要,特别是在 COVID-19 大流行爆发之后。本研究对假新闻检测系统的图神经网络 (GNN) 的现状和挑战进行了多方面、系统的回顾,并概述了使用 GNN 实现假新闻…...
HCIE认证,这些误区要避开
追求HCIE认证是许多网络工程师提升职业水平的选择之一。 然而,在这条备考之路上,存在不少误解可能会误导你的学习方向或影响你的备考效率。 了解并避开这些常见误区,将帮助你更有效地准备HCIE认证考试。 01 误区一:过分依赖题库 …...
主题切换之CSS文件篇
动态加载CSS: 利用HTML的标签,可以通过JavaScript动态改变其href属性来加载不同的CSS文件。这意味着我们可以在运行时切换整个页面的样式表,从而实现主题的变化。 分离样式: 将不同主题的样式分别放在不同的CSS文件中。例如,default_styles.…...
Vue进阶(八十八)前端测试工具介绍
文章目录 一、前言1.1 引入1.2 基础语法1.2.1 全局函数 describe 和 it1.2.2 断言 expect1.2.3 匹配器1.2.4 snapshot 快照1.2.5 测试用例覆盖率报告1.2.6 React Testing Library render1.2.7 screen1.2.8 查询函数1.2.9 waitFor1.2.10 fireEvent 和 userEvent 二、Jest 基本用…...
【录制,纯正人声】OBS录制软件,音频电流音,杂音解决办法,录制有噪声的解决办法
速度解决的方法 (1)用RNNoise去除噪声。RNNoise是一个开源的,效果不好的噪声去除器。使用方法就是点击滤镜,然后加噪声抑制RNNoise。【这方法不好用】 (2)用Krisp(https://krisp.ai/) 去除噪声。这个Kris…...
Django中drf动态过滤查询
Django中drf动态过滤查询 1、page.py 代码: from rest_framework.pagination import PageNumberPaginationclass UserPagination(PageNumberPagination):"""用户分页器"""page_size = 10 # 默认的页面数据数量page_query_param = page # 定…...
GTSAM | gtsam::PriorFactor
文章目录 概述一、定义介绍二、功能作用三、主要内容四、实例演示概述 本节介绍了GTSAM中的gtsam::PriorFactor类。 一、定义介绍 gtsam::PriorFactor 是 GTSAM(Graph-based Trajectory and Mapping)库中的一个类,用于定义先验因子。在因子图优化中,先验因子用于将一些变量…...
MMSegmentation改进:增加Kappa系数评价指数
将mmseg\evaluation\metrics\iou_metric.py文件中的内容替换成以下内容即可: 支持输出单类Kappa系数和平均Kappa系数。 使用方法:将dataset的config文件中:val_evaluator 添加mKappa,如 val_evaluator dict(typemmseg.IoUMetri…...
专栏【汇总】
专栏【汇总】 前言版权推荐专栏【汇总】付费 汇总置顶在读在学我的面试计算机重要课程java面试Java基础数据存储Java框架java提高计算机科学与技术课程算法杂项 最后 前言 2024-5-12 21:13:02 以下内容源自《【专栏】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此…...
成功解决IndexError: index 0 is out of bounds for axis 1 with size 0
成功解决IndexError: index 0 is out of bounds for axis 1 with size 0 🛠️ 成功解决IndexError: index 0 is out of bounds for axis 1 with size 0摘要引言正文内容(详细介绍)🤔 错误分析:为什么会发生IndexError&…...
C# MES通信从入门到精通(11)——C#如何使用Json字符串
前言 我们在开发上位机软件的过程中,经常需要和Mes系统进行数据交互,并且最常用的数据格式是Json,本文就是详细介绍Json格式的类型,以及我们在与mes系统进行交互时如何组织Json数据。 1、在C#中如何调用Json 在C#中调用Json相关…...
ON DUPLICATE KEY UPDATE 子句
ON DUPLICATE KEY UPDATE 是 MySQL 中的一个 SQL 语句中的子句,主要用于在执行 INSERT 操作时处理可能出现的重复键值冲突。当尝试插入的记录导致唯一索引或主键约束冲突时(即试图插入的记录的键值已经存在于表中),此子句会触发一…...
perl use HTTP::Server::Simple 轻量级 http server
cpan -i HTTP::Server::Simple 返回:已是 up to date. 但是我在 D:\Strawberry\perl\site\lib\ 找不到 HTTP\Server 手工安装:下载 HTTP-Server-Simple-0.52.tar.gz 解压 tar zxvf HTTP-Server-Simple-0.52.tar.gz cd D:\perl\HTTP-Server-Simple-…...
【STM32】基于I2C协议的OLED显示(利用U82G库)
【STM32】基于I2C协议的OLED显示(利用U82G库) 文章目录 【STM32】基于I2C协议的OLED显示(利用U82G库)一、实验背景二、U8g2介绍(一)获取(二)简介 三、实践(一)CubexMX配置(二)U8g2配…...
掌握Python3输入输出:轻松实现用户交互、日志记录与数据处理
Python 是一门简洁且强大的编程语言,广泛应用于各个领域。在 Python 编程中,输入和输出是基本而重要的操作。无论是进行用户交互、记录日志信息,还是将计算结果输出到控制台或文件,掌握这些操作都是编写高效 Python 程序的关键。本…...
用于每个平台的最佳WordPress LMS主题
你已选择在 WordPress 上构建学习管理系统 (LMS)了。恭喜! 你甚至可能已经选择了要使用的 LMS 插件,这已经是成功的一半了。 现在是时候弄清楚哪个 WordPress LMS 主题要与你的插件配对。 我将解释 LMS 主题和插件之间的区别,以便你了解要…...
pytorch 加权CE_loss实现(语义分割中的类不平衡使用)
加权CE_loss和BCE_loss稍有不同 1.标签为long类型,BCE标签为float类型 2.当reduction为mean时计算每个像素点的损失的平均,BCE除以像素数得到平均值,CE除以像素对应的权重之和得到平均值。 参数配置torch.nn.CrossEntropyLoss(weightNone,…...
【iOS】UI——关于UIAlertController类(警告对话框)
目录 前言关于UIAlertController具体操作及代码实现总结 前言 在UI的警告对话框的学习中,我们发现UIAlertView在iOS 9中已经被废弃,我们找到UIAlertController来代替UIAlertView实现弹出框的功能,从而有了这篇关于UIAlertController的学习笔记…...
django支持https
测试环境,可以用django自带的证书 安装模块 sudo pip3 install django_sslserver服务端https启动 python3 manage.py runsslserver 127.0.0.1:8001https访问 https://127.0.0.1:8001/quota/api/XXX...
算法题day41(补5.27日卡:动态规划01)
一、动态规划基础知识:在动态规划中每一个状态一定是由上一个状态推导出来的。 动态规划五部曲: 1.确定dp数组 以及下标的含义 2.确定递推公式 3.dp数组如何初始化 4.确定遍历顺序 5.举例推导dp数组 debug方式:打印 二、刷题…...
【附带源码】机械臂MoveIt2极简教程(四)、第一个入门demo
系列文章目录 【附带源码】机械臂MoveIt2极简教程(一)、moveit2安装 【附带源码】机械臂MoveIt2极简教程(二)、move_group交互 【附带源码】机械臂MoveIt2极简教程(三)、URDF/SRDF介绍 【附带源码】机械臂MoveIt2极简教程(四)、第一个入门demo 目录 系列文章目录1. 创…...
基于蚁群算法的二维路径规划算法(matlab)
微♥关注“电击小子程高兴的MATLAB小屋”获得资料 一、理论基础 1、路径规划算法 路径规划算法是指在有障碍物的工作环境中寻找一条从起点到终点、无碰撞地绕过所有障碍物的运动路径。路径规划算法较多,大体上可分为全局路径规划算法和局部路径规划算法两大类。其…...
政务云参考技术架构
行业优势 总体架构 政务云平台技术框架图,由机房环境、基础设施层、支撑软件层及业务应用层组成,在运维、安全和运营体系的保障下,为政务云使用单位提供统一服务支撑。 功能架构 标准双区隔离 参照国家电子政务规范,打造符合标准的…...
android 13 aosp 预置so库
展讯对应的main.mk配置 device/sprd/qogirn**/ums***/product/***_native/main.mk $(call inherit-product-if-exists, vendor/***/build.mk)vendor/***/build.mk PRODUCT_PACKAGES \libtestvendor///Android.bp cc_prebuilt_library_shared{name:"libtest",srcs:…...
mongo篇---mongoDB Compass连接数据库
mongo篇—mongoDB Compass连接数据库 mongoDB笔记 – 第一条 一、mongoDB Compass连接远程数据库,配置URL。 URL: mongodb://username:passwordhost:port点击connect即可。 注意:host最好使用名称,防止出错连接超时。...
基于SOA海鸥优化算法的三维曲面最高点搜索matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于SOA海鸥优化算法的三维曲面最高点搜索matlab仿真,输出收敛曲线以及三维曲面最高点搜索结果。 2.测试软件版本以及运行结果展示 MATLAB2022A版本…...
前端js解析websocket推送的gzip压缩json的Blob数据
主要依赖插件pako https://www.npmjs.com/package/pako 1、安装 npm install pako 2、使用, pako.inflate(reader.result, {to: "string"}) 解压后的string 对象,需要JSON.parse转成json this.ws.onmessage (evt) > {console.log("…...
【wiki知识库】06.文档管理接口的实现--SpringBoot后端部分
目录 一、🔥今日目标 二、🎈SpringBoot部分类的添加 1.调用MybatisGenerator 2.添加DocSaveParam 3.添加DocQueryVo 三、🚆后端新增接口 3.1添加DocController 3.1.1 /all/{ebokId} 3.1.2 /doc/save 3.1.3 /doc/delete/{idStr} …...
c,c++,go语言字符串的演进
#include <stdio.h> #include <string.h> int main() {char str[] {a,b,c,\0,d,d,d};printf("string:[%s], len:%d \n", str, strlen(str) );return 0; } string:[abc], len:3 c语言只有数组的概念,数组本身没有长度的概念,需…...
赤峰建设厅官方网站/舟山seo
在Ubuntu中vim的配置文件存放在/etc/vim目录中,配置文件名为vimrc在Fedora中vim的配置文件存放在/etc目录中,配置文件名为vimrc在终端 输入以下命令来编辑vimrc配置文件:sudo vim /etc/vim/vimrc或者 sudo gedit /etc/vim/vimrc1、显示行号 …...
县城做网站/线上营销模式有哪些
视频地址:尚硅谷大数据技术之Scala入门到精通教程(小白快速上手scala)_哔哩哔哩_bilibili 尚硅谷大数据技术Scala教程-笔记01【Scala课程简介、Scala入门、变量和数据类型、运算符、流程控制】尚硅谷大数据技术Scala教程-笔记02【函数式编程】…...
如何开发一款小游戏/汕尾网站seo
1ViewState机制是什么? ViewState机制是asp.net中对同一个Page的多次请求(PostBack)之间维持Page及控件状态的一种机制。在WebForm中每次请求完,Page对象都会被释放,对同一个Page的多次请求之间的状态信息,…...
钢铁网站模板/网站维护费一年多少钱
[PHP] 纯文本查看 复制代码public function excel(){//如果需要动态获取表头就自己查表,方法下面不多举例,毕竟不同效果不同写法,这个需要根据自己需求;以下导出代码,支持DIY表格导出,具体的看自己理解能力…...
网站建设哪个品牌好/2023最新15件重大新闻
Python 中 Eval 函数的用法 eval(str)函数很强大,官方解释为:将字符串str当成有效的表达式来求值并返回计算结果。所以,结合math当成一个计算器很好用。 eval()函数常见作用有: 1、计算字符串中有效的表达式,并返回结果…...
网站开发之ios知识扩展/惠州百度seo地址
Python 是一门更注重可读性和效率的语言,尤其是相较于 Java,PHP 以及 C 这样的语言,它的这两个优势让其在开发者中大受欢迎。 诚然,它有点老了,但仍是80后啊 —— 至少没有 Cobol 或者 Fortran 那么老。而且࿰…...