双指针法应用超级大总结

news2024/10/26 12:37:26

前言
前面很多题目都有采用双指针的思想解题,有的是最基本的双指针、有的用快慢指针、有的是滑动窗口,有的是降低时间复杂度,有的是必须采用这种思想,整的人头都大了😭😭😭。现在系统整理总结一下思想和各种类型。

题目汇总(持续补充ing)

  • 双指针法
  • 普通双指针
    • 977.有序数组的平方
  • 快慢指针法
    • 数组篇
    • 27.移除元素
    • 26.删除有序数组中的重复项
    • 283.移动零
    • 链表篇
    • 19.删除链表的倒数第N个节点
    • 142.环形链表II
  • 滑动窗口
    • 209.长度最小的子数组
    • 904.水果成篮
    • 字符串类型题目后续会补充……

双指针法

双指针是一种巧妙的算法思想,常用于遍历数组或是链表;一般需要我们定义两个指针分别指向不同的位置,根据问题的需要来改变指针的走向。使用双指针算法可以极大简化算法的时间复杂度,提高程序的效率。
一般的双指针问题可以分为如下几类:(参考博文)

  • 一般类型的双指针同向或反向,根据指针指向的数据决定指针的走向)
  • 快慢双指针 (不同移动速度的两个指针)
  • 滑动窗口同向指针且根据窗口内维护的数据决定双指针的走向)

普通双指针

关键字:数组划分 排序 遍历数组但需降低时间复杂度

思想:一般定义首尾两个对向而行的指针,遍历链表一次,两个指针分别执行不同操作,完成相应的功能。

977.有序数组的平方

题目描述:给定一个有序数组(含非正整数),要求输出平方后的顺序新数组。
暴力解法就是先平方再排序就好了
双指针解法是采用首尾两个指针对向移动,依次比较,较小的一边的对边需要往里靠一个,结束的条件就是start>end

在这里插入图片描述

class Solution {
    public int[] sortedSquares(int[] nums) {
        int length = nums.length;
        int[] new_nums = new int[length];
        int start = 0,end = length-1,index = length-1;
        while(start<=end){
            if(nums[start]*nums[start]<nums[end]*nums[end]){
                new_nums[index--] = nums[end]*nums[end--];
            }else{
                new_nums[index--]=nums[start]*nums[start++];
            }
        }
        return new_nums;
    }
}

快慢指针法

关键字:数组移除元素 链表倒数节点、环问题

数组篇

数组中的思想: 快指针遍历数组,慢指针数组负责记录制定元素。

27.移除元素

题目描述:如题
从这题可以看出数组增删操作的不便,还是链表在这方面好操作,遍历一次,改变节点指向就行,数组操作需要借助快慢指针优化时间复杂度。

  • 暴力解法

暴力解法就是双循环,先找到待删除的元素,因为是在数组中,元素内存连续,所以需要赋值覆盖。
注意 (1) 内循环边界判断j不要越界 (2) 每次找到覆盖后,外循环的索引i应该不动,继续判断是否是连续相同待删除数值元素

class Solution {
    public int removeElement(int[] nums, int val) {
        int count = 0;
        for(int i = 0;i<nums.length-count;i++){
            if(nums[i]==val){
                count++;
                for(int j = i+1;j<nums.length;j++){
                    nums[j-1]=nums[j];
                }
                i--;
            }
        }
        return nums.length-count;
    }
}
  • 快慢指针法

利用快指针遍历,找到不同于val的元素则赋值给慢指针的新数组相同则跳过进入下一次遍历寻找

class Solution {
    public int removeElement(int[] nums, int val) {
        int slow = 0;
        for(int fast = 0;fast<nums.length;fast++){
            if(nums[fast]!= val){
                nums[slow++]=nums[fast];
            }
        }
        return slow;
    }
}

26.删除有序数组中的重复项

题目描述:如题,但还是上一个数组删除元素的题目,只不过现在val是变化的。
注意 慢指针数组赋值时,需要提前++,因为慢指针默认有第一个元素,也就是原数组的第一个元素,后续索引从1开始,有新元素则赋值给慢指针数组,这时候需要提前移动一位

class Solution {
    public int removeDuplicates(int[] nums) {
        int slow = 0;
        for(int fast = 1;fast<nums.length;fast++){
            if(nums[fast]!=nums[slow]){
                nums[++slow]=nums[fast];
            }
        }
        return slow+1;
    }
}

283.移动零

题目描述:将数组中的零移动到数组的后面。
用快慢指针的方法,那么这个和27.数组删除元素的题目一样,这个找非零元素存起来就行,不过还需要一个额外的操作,剩余的元素置零。

class Solution {
    public void moveZeroes(int[] nums) {
        int slow = 0;
        for(int fast=0;fast<nums.length;fast++){
            if(nums[fast]!=0){
                nums[slow++]=nums[fast];
            }
        }
        for(int count = slow++;count<nums.length;count++){
            nums[count]= 0;
        }
    }
}

链表篇

链表中的思想: 两个指针以不同的速度,固定节点数目的间隔遍历链表。

(这部分题目前面的博文已总结,不再赘述)

19.删除链表的倒数第N个节点

题目描述:如题
快指针比慢指针多走n步即可,同样的还有求有序链表的中位数的(fast=fast.next.next;slow=slow.next;

142.环形链表II

题目描述:验证链表是否有环,有的话输出入口点。
追击相遇问题,快指针比慢指针快一步就可以在环里追上,入口点取决于相遇点和头结点。

滑动窗口

关键字:数组的子数组 字符串的子串 同向移动
此部分参考博文-详解双指针算法(三)之滑动窗口

209.长度最小的子数组

题目描述:如题
左右两个窗口指针同向移动,右指针负责引入元素构造窗口,当窗口符合缩小条件时,左指针移动缩小窗口
结束条件是右指针出去数组。对于数组【1,7,1】,target=7的单子数组情况,虽然while循环结束后左指针>右指针,但结束完while后,一次for循环也结束了,此时两指针都同时指向下一个点,所以不用考虑左指针超限的情况,只需要考虑右指针就可以。
在这里插入图片描述

 class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int sum = 0;
        int min = Integer.MAX_VALUE;
        for(int windowStart = 0,windowEnd = 0;windowEnd<nums.length;windowEnd++){
            sum +=nums[windowEnd];
            while(sum>=target){
                min =min<(windowEnd-windowStart+1)? min:(windowEnd- windowStart+1);
                sum-=nums[windowStart++];
            }
        }
         return min == Integer.MAX_VALUE ? 0 : min;
    }
}

904.水果成篮

题目描述:找到一个最长的连续子数组,这个数组里元素最多有两种。
这是求一个连续子数组问题,所以考虑用滑动窗口,右指针遍历,左指针控制窗口。
本题的数组结构主要有以下几个类型:仅一种元素两种元素>两种元素
一种元素,只需计算数组长度即可,right(数组最后一个元素)-left(数组第一个元素)+1
两种元素,判断出第二个元素,添加到新数组中,后续没有元素与这个新数组的两个元素一致,输出结果
>两种元素,这主要涉及left指针移动,每个合法窗口内都只有两种元素,我的做法是先找到第三种元素,然后left就是第三种元素前的连续元素组的第一个,比如【1,2,1,1,3,1】,第二个窗口的两种元素是这两个,left不一定都挨着第三种元素。

class Solution {
    public int totalFruit(int[] fruits) {
        int[] num = new int[2];
        num[0] = fruits[0];
        int count = 1;
        int max = 1;
        for(int right = 1,left = 0;right<fruits.length;right++){
            if(count == 1&&fruits[right]!=num[0]){
                num[1] = fruits[right];
                count = 2;
            }
            if(count == 2&&(fruits[right]!=num[0]&&fruits[right]!=num[1])){
                left = right-1;
                while(fruits[left-1]==fruits[left]){
                    left--;
                }
                max = (right-left+1)>=max ? (right-left+1):max;
                num[0] = fruits[left];
                num[1] = fruits[right];
                continue;
            }
            max = (right-left+1)>=max ? (right-left+1):max;
        }
        return max;
    }
}

字符串类型题目后续会补充……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2223967.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Boot技术中小企业设备管理系统设计与实践

6系统测试 6.1概念和意义 测试的定义&#xff1a;程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为&#xff1a; 目的&#xff1a;发现程序的错误&#xff1b; 任务&#xff1a;通过在计算机上执行程序&#xff0c;暴露程序中潜在的错误。 另一个…

Could not retrieve mirrorlist http://mirrorlist.centos.org错误解决方法

文章目录 背景解决方法 背景 今天在一台新服务器上安装nginx&#xff0c;在这个过程中需要安装相关依赖&#xff0c;在使用yum install命令时&#xff0c;发生了以下报错内容&#xff1a; Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7&archx8…

SpringMVC实战:构建高效表述层框架

文章目录 1. SpringMVC简介和体验1.1 介绍1.2 主要作用1.3 核心组件和调用流程1.4 快速体验 2. SpringMVC接收数据2.1 访问路径设置2.2 接收参数2.2.1 param和json参数比较2.2.2 param参数接收2.2.3 路径参数接收2.2.4 json参数接收 2.3 接收cookie数据2.4 接收请求头数据2.5 原…

10340 文本编辑器(vim)

经验值&#xff1a;1600 时间限制&#xff1a;1000毫秒 内存限制&#xff1a;512MB 经开区2023年信息学竞赛试题 不许抄袭&#xff0c;一旦发现&#xff0c;直接清空经验&#xff01; 题目描述 Description 李明正在学习使用文本编辑器软件 Vim。与 Word、VSCode 等常用的…

用扣子模板,走AI捷径,这个双11,大模型要发威了?

AI离我们越来越近&#xff0c;还是越来越远&#xff1f; 一年前&#xff0c;ChatGPT刚出现那会儿&#xff0c;AI极其火热&#xff0c;很多国内企业奋不顾身的杀进去&#xff0c;或自研或投资或结盟&#xff0c;那时&#xff0c;感觉AI已经离我们很近了&#xff0c;一场商业革命…

单链表OJ题:移除链表元素(力扣)

目录 解法一&#xff1a;带头节点的新链表 解法二&#xff1a;不带头节点的新指向关系链表 总结 这是一道简单的力扣题目&#xff0c;关于解法的话&#xff0c;这里提供了二种思路&#xff0c;重点解释前两种&#xff0c;还有一种思路好想&#xff0c;但是时间复杂度为O(n^2…

使用Prometheus对微服务性能自定义指标监控

背景 随着云计算和容器化技术的不断发展&#xff0c;微服务架构逐渐成为现代软件开发的主流趋势。微服务架构将大型应用程序拆分成多个小型、独立的服务&#xff0c;每个服务都可以独立开发、部署和扩展。这种架构模式提高了系统的可伸缩性、灵活性和可靠性&#xff0c;但同时…

Java.9--集合

一、Collection接口 -->单列集合&#xff08;共享给大家&#xff09; .add();把给定的对象添加到当前集合中 clear();清空集合中所有的元素 remove();把给定的对象在当前集合中删除 contains();判断当前集合中是否包含给定的对象 isEmpty();判断当前集合是否为空 siz…

SQL注入之sqlilabs靶场21-30题

重点插入&#xff1a;html表 第二十一题 分析过程&#xff1a;&#xff08;没有正确的账号密码是否能拿到Cookie&#xff1f;最后注释好像只能使用#&#xff0c;--好像无法注释&#xff09; 查看源码 这里输入账号密码处被过滤了 但Cookie被base64编码了 可以从Cookie入手 …

智联招聘×Milvus:向量召回技术提升招聘匹配效率

01. 业务背景 在智联招聘平台&#xff0c;求职者和招聘者之间的高效匹配至关重要。招聘者可以发布职位寻找合适的人才&#xff0c;求职者则通过上传简历寻找合适的工作。在这种复杂的场景中&#xff0c;我们的核心目标是为双方提供精准的匹配结果。在搜索推荐场景下&#xff0c…

Ollama+Open WebUI,windows部署一个本地AI

在Ollama官网下载&#xff0c;点击DownLoad 下载完之后进行安装&#xff0c;配置环境变量&#xff0c;完成后打开CMD命令行工具测试 运行并下载模型 之后选择Open WebUI作为图形化界面 &#x1f680; Getting Started | Open WebUI 运行Docker命令 docker run -d -p 3000:80…

【Sublime Text】设置中文 最新最详细

在编程的艺术世界里&#xff0c;代码和灵感需要寻找到最佳的交融点&#xff0c;才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里&#xff0c;我们将共同追寻这种完美结合&#xff0c;为未来的世界留下属于我们的独特印记。 【Sublime Text】设置中文 最新最详细 开…

万字图文实战:从0到1构建 UniApp + Vue3 + TypeScript 移动端跨平台开源脚手架

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f343; vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f…

团结引擎内置 AI 助手团结 Muse Chat 测试版上线!新功能怎么用?能做什么?

在开发过程中&#xff0c;快速获得精准的技术支持能够有效提高开发效率。生成式 AI 的出现为实现实时技术支持提供了新的机会。Unity 中国积极探索 AI 在开发中的应用&#xff0c;并在团结引擎 1.3.0 版本中上线了新功能&#xff1a;团结 Muse Chat。 团结 Muse Chat 是 Unity…

【linux】服务器Ubuntu20.04安装cuda11.8教程

【linux】服务器Ubuntu20.04安装cuda11.8教程 文章目录 【linux】服务器Ubuntu20.04安装cuda11.8教程到官网找到对应版本下载链接终端操作cudnn安装到官网下载下载后解压进入解压后的目录&#xff1a;将头文件复制到 /usr/local/cuda/include/ 目录&#xff1a;将库文件复制到 …

Matlab学习02-matlab中的数据显示格式及符号变量

目录 一&#xff0c;关系运算和逻辑运算 二&#xff0c;变量 三&#xff0c;数据显示格式 四&#xff0c;符号运算 1&#xff0c;创建符号变量 2&#xff0c;数值矩阵转换成符号矩阵 一&#xff0c;关系运算和逻辑运算 在matlab中&#xff0c;只要数值不是 &#xff0…

Lucas带你手撕机器学习——岭回归

岭回归&#xff08;Ridge Regression&#xff09; 一、背景与引入 在进行线性回归分析时&#xff0c;我们常常面临多重共线性的问题。多重共线性指的是自变量之间高度相关&#xff0c;这会导致回归系数的不稳定性&#xff0c;使得模型的预测能力降低。传统的线性回归通过最小…

【R + Python】iNaturalist 网站图片下载 inat api

文章目录 一、iNaturalist 简介二、R语言API&#xff1a;rinat三、示例3.1 获取观测数据3.2 绘制可视化图像函数用法 3.4 在区域网格中搜索3.5 下载图片3.51 提取图片 url3.52 下载图片: R语言3.53 下载图片: python 四、获取详细rinat包的文档 一、iNaturalist 简介 &#x1…

微服务网关Zuul

一、Zuul简介 Zuul是Netflix开源的微服务网关&#xff0c;包含对请求的路由和过滤两个主要功能。 1&#xff09;路由功能&#xff1a;负责将外部请求转发到具体的微服务实例上&#xff0c;是实现外部访问统一入口的基础。 2&#xff09;过滤功能&#xff1a;负责对请求的过程…

ReactOS系统中搜索给定长度的空间地址区间中的二叉树

搜索给定长度的空间地址区间 //搜索给定长度的空间地址区间 MmFindGap MmFindGapTopDown PVOID NTAPI MmFindGap(PMADDRESS_SPACE AddressSpace,ULONG_PTR Length,ULONG_PTR Granularity,BOOLEAN TopDown );PMADDRESS_SPACE AddressSpace,//该进程用户空间 ULONG_PTR Length,…