双指针算法:快速解决问题的小技巧(Java代码实现)

news2024/11/15 2:03:07

“人的一生是短暂的,但如果卑鄙地过这短暂的一生,那就太长了。”

文章目录

  • 前言
    • 文章有误敬请斧正 不胜感恩!
    • 双指针
      • 简介
      • 对撞指针
      • 快慢指针
      • 例题
        • 聪明的小羊肖恩
        • 神奇的数组
        • 盛最多的水
  • 总结


前言

写在开始:
双指针算法是一种经典且高效的算法技巧,常用于数组、字符串等线性数据结构中的各种问题。它通过两个指针的协同移动,解决了传统暴力法需要 O(n²) 复杂度的问题,优化至 O(n)。双指针算法主要分为对撞指针和快慢指针两类,前者常用于解决有序数组和字符串的问题,后者更适合处理需要区间或步长变化的场景。掌握双指针技巧,不仅能提高解题效率,还能帮助我们更深入理解数据结构的特性与变化规律。

双指针算法其实就是通过两个“指针”来操作数据,虽然我们叫它指针,但实际上就是两个变量,
它们指的是数据中的不同位置。这个方法特别适合解决像数组、字符串这类线性结构的问题。
传统的暴力算法可能需要遍历很多次才能找到答案,而双指针通过巧妙的移动指针,
大大减少了重复操作,从而提高了效率。常见的双指针有两种,一种是从两边往中间走的对撞指针,
另一种是快慢指针,一个快一个慢,逐步缩小范围来解决问题。

在这里插入图片描述


文章有误敬请斧正 不胜感恩!

以下是本篇文章正文内容,


双指针

简介

双指针算法是一种常用的算法技巧,它通常用于在数组或字符串中进行快速查找、匹配、排序或移动操作

双指针并非真的用指针实现,一般用两个变量来表示下标 (在后面都用指针来表示)

双指针算法使用两个指针在数据结构上进行迭代,并根据问题的要求移动这些指针

双指针往往也和单调性、排序联系在一起,在数组的区间问题上,暴力法的时间复杂度往往是O(n^2)的,但双指针利用“单调性”可以优化到O(n).

常见的双指针模型有:

  1. 对撞指针
  2. 快慢指针

对撞指针

指的是两个指针 left、right (简写为l,r) 分别指l向序列第一个元素和最后一个元素

然后l指针不断递增,r不断递减,直到两个指针的值相撞或错开 (即 l >= r),或者满足其他要求的特殊条件为止。

对撞指针一般用来解决有序数组或者字符串问题 (常见于区间问题)

查找有序数组中满足某些约束条件的一组元素问题: 比如二分查找、数字之和等问题字符串反转问题:反转字符串、回文数等问题.

  1. 使用两个指针 left,right。let 指向序列第一个元素,即: left = l,right 指向序列最后一个元素,即: right = n。
  2. 在循环体中将左右指针相向移动,当满足一定条件时,将左指针右移,let ++。当满足另外定条件时,将右指针左移,right –
  3. 直到两指针相撞(即 left == right),或者满足其他要求的特殊条件时,跳出循环体

img

快慢指针

快慢指针一般比对撞指针更难想,也更难写

指的是两个指针从同一侧开始遍历序列,且移动的步长一个快一个慢

移动快的指针被称为快指针,移动慢的指针被称为慢指针

为了方便理解,我们成快指针为r,慢指针为1,这样慢指针和快指针构成区间[l,r]

两个指针以不同速度、不同策略移动,直到快指针移动到数组尾端,或者两指针相交,或者满足其他特殊条件时为止

  1. 使用两个指针1、r1一般指向序列第一个元素,即: 1= 1,r一般指向序列第零个元素,即:r = 0。即初始时区间[l, r]= [1,]表示为空区间
  2. 在循环体中将左右指针向右移动。当满足一定条件时,将慢指针右移,即1++。当满足另外一定条件时 (也可能不需要满足条件) ,将快指针右移,即r++,保持[l,r]为合法区间
  3. 到指针移动到数组尾端 (即l== n且r== n),或者两指针相交,或者满足其他特殊条件时跳出循环体

img

例题

聪明的小羊肖恩
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int left = scan.nextInt();
        int right = scan.nextInt();
        int[] arr = new int[n];
        for(int i=0;i<n;i++){
            arr[i] = scan.nextInt();
        }
        Arrays.sort(arr);
        System.out.println(calc(arr,right)-calc(arr,left-1));
        scan.close();
    }
    static long calc(int[] arr,int t){
        long ans = 0;
        int l = 0 , r = arr.length - 1;
        while(l < r){
            while(l<r && arr[r] + arr[l] > t){
                r--;
            }
            ans += r - l;
            l++;
        }
        return ans;
    }
}
神奇的数组
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int[] arr = new int[n];
        for(int i=0;i<n;i++){
            arr[i] = scan.nextInt();
        }
        int l=0,r=0,rs=0;
        long ans = 0;
        while(l<n){
            while(r<n && ((rs^arr[r]) == (rs + arr[r]))){
                rs ^= arr[r];
                r++;
            }
            ans += r - l;
            rs ^= arr[l];
            l++;
        }
        System.out.println(ans);
        scan.close();
    }
}
盛最多的水

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

class Solution {
    public int maxArea(int[] height) {
        int i = 0, j = height.length - 1, res = 0;
        ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/056355574f954b2794e5e37b99b20360.jpeg#pic_center)

            res = height[i] < height[j] ?
            Math.max(res, (j - i) * height[i++]):
            Math.max(res, (j - i) * height[j--]);
        }
        return res;
    }
}

总结

双指针算法的核心在于两个指针的相互配合,通过灵活调整指针的移动策略,能够有效地解决很多复杂度较高的问题。无论是对撞指针,还是快慢指针,都是在特定场景下优化问题求解的一种利器。在面对算法问题时,我们要善于通过分析数据的单调性、区间的划分来运用双指针算法,从而提升代码的效率和简洁性。


在这里插入图片描述

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

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

相关文章

“中秋快乐”文字横幅的MATLAB代码生成

中秋快乐呀朋友们&#xff01;&#xff01;&#xff01; 给大家带来一个好玩的代码&#xff0c;能够生成“中秋快乐”的横幅文字&#xff0c;比较简单&#xff0c;当然你也可以根据自己的需求去更改文字和背景&#xff0c;废话不多说&#xff0c;直接展示。 文字会一直闪烁&…

智能BI项目第三期

AIGC AI 提问技巧 为了让 Al 更好地理解我们的输入&#xff0c;并给出预期精确的输出&#xff0c;需要严格控制我们的提问词。 1.使用系统预设 控制输入格式(便于Al精确地理解我们的需求) 你是一个数据分析师和前端开发专家&#xff0c;接下来我会按照以下固定格式给你提供…

《深度学习》PyTorch框架 优化器、激活函数讲解

目录 一、深度学习核心框架的选择 1、TensorFlow 1&#xff09;概念 2&#xff09;优缺点 2、PyTorch 1&#xff09;概念 2&#xff09;优缺点 3、Keras 1&#xff09;概念 2&#xff09;优缺点 4、Caffe 1&#xff09;概念 2&#xff09;优缺点 二、pytorch安装 1、安装 2、…

传输层协议 —— UDP协议

目录 0.前言 1.UDP协议格式 16位源端口和目的端口 16位UDP长度 16位校验和 2.UDP协议特点 无连接 不可靠 面向数据报 3.UDP的缓冲区 0.前言 首先&#xff0c;我们得明确一点&#xff0c;网络模型是分层的。自底向上分别是物理层、数据链路层、网络层、传输层、应用层…

Nginx反向代理出现502 Bad Gateway问题的解决方案

&#x1f389; 前言 前一阵子写了一篇“关于解决调用百度翻译API问题”的博客&#xff0c;近日在调用其他API时又遇到一些棘手的问题&#xff0c;于是写下这篇博客作为记录。 &#x1f389; 问题描述 在代理的遇到过很多错误码&#xff0c;其中出现频率最高的就是502&#x…

JavaEE:网络编程(套接字)

文章目录 Socket套接字TCP和UDP的区别有连接/无连接可靠传输/不可靠传输面向字节流/面向数据报全双工/半双工 UDP/TCP api的使用UDPDatagramSocketDatagramPacketInetSocketAddress练习 TCPServerSocketSocket练习 Socket套接字 Socket是计算机网络中的一种通信机制&#xff0…

驱动开发知识点

裸机开发 ——————————————linux驱动 SOC&#xff1a; 定义&#xff1a;SOC&#xff0c;全称System on Chip&#xff0c;是一种集成了多个功能模块的芯片&#xff0c;包括处理器、内存、外设、接口等。它将原本分散在多个芯片上的功能集成到一个芯片上&#xff0…

一个基于 laravel 和 amis 开发的后台框架, 友好的组件使用体验,可轻松实现复杂页面(附源码)

前言 随着互联网应用的发展&#xff0c;后台管理系统的复杂度不断增加&#xff0c;对于开发者而言&#xff0c;既要系统的功能完备&#xff0c;又要追求开发效率的提升。然而&#xff0c;传统的开发方式往往会导致大量的重复劳动&#xff0c;尤其是在构建复杂的管理页面时。有…

不限学历!这个证书在上海太香了!利于积分、落户、抵扣个税...

一、软考是什么&#xff1f; “软考”全称&#xff1a;计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff0c;关于它你需要知道&#xff1a; 1、软考是全国性考试&#xff1a;软考实行全国统一规划&#xff0c;实行统一大纲&#xff0c;统一试题&#xff…

【vulhub】Os-hackNos-1

&#x1f3d8;️个人主页&#xff1a; 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞&#x1f44d;收藏&#x1f497;支持一下哦 【vulhub】Os-hackNos-1 环境搭建漏洞复现 环境搭建 进入vulnhub官网 https://vulnhub.com 下载镜像 在虚拟机中打开镜像文件…

100行Python代码实现FastAPI Websocket 聊天室(纯协程方案)

本文发表于入职啦(公众号: ruzhila) 大家可以访问入职啦学习更多的编程实战。 项目地址 代码已经开源&#xff0c; fastapi_chatroom &#x1f44f; 欢迎Star 代码运行效果&#xff1a; 所有的项目都在github上开源&#xff1a;100-line-code 欢迎Star &#x1f44f; 用100行…

open sora1.1容器构建教程指南

一、介绍 Open-Sora 1.1 项目是 Colossal AI 团队开发的一个完全开源的视频生成项目&#xff0c;该项目致力于高效制作高质量视频&#xff0c;并通过开源原则实现先进视频生成技术的低成本普及。 1. 项目背景与目标 Open-Sora 项目旨在通过提供开源的模型、工具和内容&#…

idea使用阿里云服务器运行jar包

说明&#xff1a;因为我用的阿里云服务器不是自己的&#xff0c;所以一些具体的操作可能不太全面。看到一个很完整的教程&#xff0c;供参考。 0. 打包项目 这里使用的是maven打包。 在pom.xml中添加以下模块。 <build><plugins><plugin><groupId>org…

JDBC导图

思维歹徒 一、使用步骤 二、SQL注入 三、数据库查询&#xff08;查询&#xff09; 四、数据库写入&#xff08;增删改&#xff09; 五、Date日期对象处理 六、连接池使用 创建连接是从连接池拿&#xff0c;释放连接是放回连接池 七、事务和批次插入 八、Apache Commons DBUtil…

进程监控与管理详解

一、进程的定义: 进程process是正在运行的程序,包括: 分配的内存地址空间 安全属性、包括所有权和特权 一个或多个线程 进程状态 进程的环境包括: 本地和全局变量 当前调度上下文…

多目标优化算法(Multi-Objective Optimization Algorithms, MOOA)介绍

在现实世界中&#xff0c;许多问题都涉及到多个目标的权衡和优化。例如&#xff0c;在工程设计中&#xff0c;可能需要同时考虑成本、效率和可靠性&#xff1b;在资源管理中&#xff0c;可能需要平衡环境保护和经济效益。多目标优化算法&#xff08;Multi-Objective Optimizati…

bmp格式图片怎么转换jpg?这几种转换方法超级好用!

bmp格式图片怎么转换jpg&#xff1f;BMP格式&#xff0c;这一历史悠久的图像编码方式&#xff0c;正逐渐在数字时代的浪潮中显得力不从心&#xff0c;其边缘化的趋势愈发明显&#xff0c;这一现象的根源&#xff0c;在于BMP格式固有的局限性难以匹配现代用户对于图像处理的多元…

【Python】探索Magenta:音乐与艺术的机器智能创作

下班了&#xff0c;今天的苦就先吃到这里。 在人工智能的浪潮中&#xff0c;机器学习技术正逐渐渗透到艺术创作的各个领域。今天&#xff0c;我们来探索一个特别的项目——Magenta&#xff0c;它是由Google Brain团队发起的&#xff0c;旨在使用机器智能生成音乐和艺术。这个项…

Lucene详解介绍以及底层原理说明

文章目录 什么是Lucene?示意图1. 倒排索引2. 索引创建过程3. 数据存储4. 搜索过程5. 相关性评分 Lucene底层原理1. 倒排索引2. 索引创建过程3. 数据存储4. 搜索过程5. 相关性评分 什么是Lucene? Lucene是一个高性能的全文搜索引擎库&#xff0c;它基于倒排索引技术实现快速、…

Threejs之看房案例(下)

本文目录 前言最终效果1、点精灵1.1 添加点精灵1.2 点精灵效果2、添加事件2.1 鼠标移动事件2.1.1 效果2.2 鼠标点击事件2.2.1 效果2.3 切换互通3. 完整代码前言 在Threejs之看房案例(上)这篇博客中我们已经完成了大厅的3d观看效果,但是我们会发现如果想去其他房间观看,没有…