leetCode-hot100-数组专题之双指针

news2024/10/5 9:13:51

数组双指针专题

  • 1.同向双指针
    • 1.1例题
      • 26.删除有序数组中的重复项
      • 27.移除元素
      • 80.删除有序数组中的重复项 Ⅱ
  • 2.相向双指针
    • 2.1例题
      • 11.盛最多水的容器
      • 42.接雨水
      • 581.最短无序连续子数组

双指针在算法题中很常见,下面总结双指针在数组中的一些应用,主要分为两类:

1.同向双指针

题目中有原地不适用额外空间等关键词,一般解决方法是定义两个快慢指针:
快指针:用来遍历数组,并进行一些规则匹配
慢指针:用来表示结果数组,即当前符合条件的数组

最后一般是返回慢指针的下标,需要注意的是有时候不能只返回慢指针的下标,可能需要+1,需要根据实际情况分析。

1.1例题

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

思路:
本题设置一个辅助下标指针idx指向数组的第一个元素,然后往后遍历数组,如果遇到了相同的元素就跳过,遇到不同的元素则加入到辅助下标的后一个元素,依次类推,直到遍历数组结束,最后返回idx+1即为所求的长度。详细的视频讲解点击视频讲解-删除有序数组中的重复项。
时间复杂度:
时间复杂度为O(n),只进行了一次数组的遍历。
代码实现:

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

27.移除元素

思路:
本题的思路和第26题一样,需要一个辅助下标idx,遍历整个数组,当遇到数组元素不等于val时,则将其加入到删除后的数组中,同时辅助下标后移,遍历结束后返回辅助下标idx的值即可,详细的视频讲解点击视频讲解-移除元素。
时间复杂度:
时间复杂度为O(n)n为数组的长度。
代码实现:

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

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

思路:
本题采用双指针来求解,解法和26.删除有序数组中的重复项类似,但是由于本题中每个元素可以出现两次,所以将idx设置为1,设置前两个位置为结果数组,第二个指针从索引为2开始,比较当前元素和结果数组中的倒数第二个元素的值是否相等(即nums[idx - 1],注意这里不要使用nums[--idx],因为这样会改变idx的值,导致索引不正确),如果相等则i++,继续向后遍历,如果不相等则加入到结果数组中(这里可以这样做的原因是nums有序数组!!!如果是无序数组则不能这么做),下面是一个模拟的例子:
在这里插入图片描述
视频讲解点击视频讲解-删除有序数组中的重复项 Ⅱ
时间复杂度:
时间复杂度为O(n),其中n为数组的长度。
代码实现:

class Solution {
    public int removeDuplicates(int[] nums) {
        if(nums.length <= 2) return nums.length;
        int idx = 1;
        for(int i = 2;i < nums.length ; i++){
            if(nums[i] != nums[idx - 1]){
                nums[++idx] = nums[i];
            }
        }
        return idx + 1;
    }
}

2.相向双指针

双指针 一般是一个在开头,一个在结尾,两者相向处理问题,一般用来确定某个符合条件的子数组,需要维护左右边界。

2.1例题

11.盛最多水的容器

思路:
本题采用双指针来求解,由于盛水的体积为宽✖高,因此可以定义首尾两个指针,枚举出不同高度的体积并取最大值,在移动指针的过程中,应该移动高度较小的指针,因为盛水的高度是由短板来决的,如图,不同的颜色表示每次移动指针后得到的体积。视频讲解点击视频讲解-盛最多水的容器。
在这里插入图片描述

时间复杂度:
时间复杂度为O(n),空间复杂度O(1)
代码实现:

class Solution {
    public int maxArea(int[] height) {
        int ans = 0;
        int l = 0;
        int r =height.length - 1;
        while(l < r){
            ans = Math.max(ans,Math.min(height[l],height[r]) * (r-l));
            if(height[l] < height[r]) l++;
            else r--;
        }
        return ans;
    }
}

42.接雨水

思路:
本题采用双指针来求解,类似于11.盛水最多的容器,盛水的多少取决于左右柱子里较低的一个。通过维护左边和右边的最大高度,来计算整个数组中的装水容量,定义两个变量lmaxrmax,初始值都为0,用于记录当前位置左边和右边的最大高度,不断更新左右两边的最大高度来计算每个位置的水位,然后将各个位置的水位差累加起来得到总的装水容量,下面是一个模拟的例子:
在这里插入图片描述
视频讲解点击视频讲解-接雨水。
时间复杂度:
这段代码的时间复杂度是O(n),其中n是height数组的长度。由于只使用了一个while循环来遍历height,没有嵌套的循环,因此时间复杂度是线性的。
代码实现:

class Solution {
    public int trap(int[] height) {
        int l = 0;
        int r = height.length - 1;
        int lmax = 0;
        int rmax = 0;
        int ans = 0;
        while(l < r){
            lmax = Math.max(lmax,height[l]);
            rmax = Math.max(rmax,height[r]);
            if(lmax < rmax){
                ans += lmax - height[l];
                l++;
            } else{
                ans += rmax - height[r];
                r--;
            }
        }
        return ans;
    }
}

581.最短无序连续子数组

思路:
本题采用双指针解决,分别从数组的两端进行遍历,确定结果数组的左右边界。确定左边界的条件如果当前元素小于左边界处的最大值,则更新右边界,否则更新左边界的最大值(左边界的右边不应该出现比左边界小的值);确定右边界的条件是如果当前元素大于右边界处的最小值,则更新左边界,否则更新右边界的最小值(右边界的左边不应该出现比右边界大的值),得到左右边界后返回子数组的长度即可。
时间复杂度:
时间复杂度为O(n)n为数组长度。
代码实现:

class Solution {
    public int findUnsortedSubarray(int[] nums) {
        //初始化工作:
        //start、end分别是从前向后和从后向前遍历数组的两个指针
        //需要注意的是end不是从len - 1开始,初始值应该为-1,这是为了处理数组本来就是有序数组的情况
        //lmax、rmin分别是遍历过程中维护的左边界的最大值和右边界的最小值
        int len = nums.length;
        int start = 0;
        int end = -1;
        int lmax = nums[0];
        int rmin = nums[len - 1]; 

        for(int i = 0;i < len ; i++){
            //确定左边界
            if(nums[i] < lmax){
                end = i;
            } else {
                lmax = nums[i];
            }
            //确定右边界
            if(nums[len - i - 1] > rmin){
                start = len - i -1;
            } else {
                rmin = nums[len - i -1];
            }
        }
        return end - start + 1;
    }
}

参考资料:双指针-数组

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

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

相关文章

解决“Failed to restart udev.service“

报错信息 Failed to restart udev.service: Unit systemd-udevd.service is not loaded properly: Exec format error. See system logs and ‘systemctl status udev.service’ for details. invoke-rc.d: initscript udev, action “restart” failed. ● systemd-udevd.ser…

Day25:Leetcode:669. 修剪二叉搜索树 + 108.将有序数组转换为二叉搜索树 + 538.把二叉搜索树转换为累加树

LeetCode&#xff1a;669. 修剪二叉搜索树 问题描述 解决方案&#xff1a; 1.思路 2.代码实现 class Solution {public TreeNode trimBST(TreeNode root, int low, int high) {if (root null) {return null;}if (root.val < low) {return trimBST(root.right, low, hi…

跳房子游戏-第13届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第71讲。 跳房子游戏&#…

一.ffmpeg 将内存中的H264跟PCM 数据流合成多媒体文件

在有一些嵌入式平台中&#xff0c;H264数据流一般来自芯片内部的硬编码器&#xff0c; AAC音频数据则是通过采集PCM进行软编码&#xff0c;但是如何对它实时进行封装多媒体文件 &#xff0c;参考ffmpeg example&#xff0c;花了一些时间终于实现了该功能。 流程图如下&#xf…

什么是经典蓝牙模块?

什么是经典蓝牙模块&#xff1f;   前面我们已经就蓝牙模块的概念做了了解&#xff0c;随着时间的推移&#xff0c;产品越来越智能&#xff0c;需要的蓝牙模块也就越来越广泛&#xff0c;本篇文章我们就一起了解下什么是经典蓝牙模块。   经典蓝牙模块(BT)泛指支持蓝牙协议…

ClickHouse配置与使用

静态IP配置 # 修改网卡配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33# 修改文件内容 TYPEEthernet PROXY_METHODnone BROWSER_ONLYno BOOTPROTOstatic IPADDR192.168.18.128 NETMASK255.255.255.0 GATEWAY192.168.18.2 DEFROUTEyes IPV4_FAILURE_FATALno IPV6INIT…

AI办公自动化-kimi批量在多个Excel工作表中绘制柱状图

工作任务和目标&#xff1a;批量在多个Excel工作表中生成一个柱状图 第一步&#xff0c;在kimi中输入如下提示词&#xff1a; 你是一个Python编程专家&#xff0c;完成下面任务的Python脚本&#xff1a; 打开文件夹&#xff1a;F:\aivideo 读取里面所有的xlsx文件&#xff1…

【云原生之】K8s 管理工具 kubectl 详解(二)

一、项目的生命周期 创建–>发布–>更新–>回滚–>删除 1.1、创建kubectl create命令 创建并运行一个或多个容器镜像。创建一个deployment 或job 来管理容器。 kubectl create --help kubectl -n 命名空间 create deployment 资源名称 --image镜像 --port容器的端…

useTransition:开启React并发模式

写在前面&#xff1a;并发 并发模式&#xff08;Concurrent Mode&#xff09;1的一个关键特性是渲染可中断。 React 18 之前&#xff0c;更新内容渲染的方式是通过一个单一的且不可中断的同步事务进行处理。同步渲染意味着&#xff0c;一旦开始渲染就无法中断&#xff0c;直到…

将某一个 DIV 块全屏展示

文章目录 需求分析 需求 上节我们研究了如何将页面中的指定 div 下载为图片&#xff1a;跳转查看 本节演技一下如何将 DIV 全屏展示 全屏展示某一个 DIV 分析 其实就是模拟键盘动作 F11 var element document.getElementById(pic) var requestMethod element.requestFullS…

Alinx xc7z020 原理图

时钟引脚 CLK&#xff1a;U18 复位 RST&#xff1a;N15 扩展接口 J10 J11 PL LED

实战:生成个性化词云的Python实践【7个案例】

文本挖掘与可视化&#xff1a;生成个性化词云的Python实践【7个案例】 词云&#xff08;Word Cloud&#xff09;&#xff0c;又称为文字云或标签云&#xff0c;是一种用于文本数据可视化的技术&#xff0c;通过不同大小、颜色和字体展示文本中单词的出现频率或重要性。在词云中…

CVPR2022医疗图像-GBCNet网络:胆囊癌(GBC)超声(USG)图像检测模型

Surpassing the Human Accuracy:Detecting Gallbladder Cancer from USG Images with Curriculum Learning&#xff1a;超越人类的准确性:基于课程学习的USG图像检测胆囊癌 目录 一、背景与意义 二、介绍 三、网络框架 3.1 区域选择网络 3.2 MS-SoP分类器 3.3 多尺度块 …

前端加载excel文件数据 XLSX插件的使用

npm i xlsx import axios from axios; axios //这里用自己封装的http是不行的&#xff0c;踩过坑.get(url,{ responseType: "arraybuffer" }).then((re) > {console.log(re)let res re.datavar XLSX require("xlsx");let wb XLSX.read(r…

20240523每日运维--------聊聊docker简介(一)

dotCloud 说Docker&#xff0c;必不可免不得不说dotCloud&#xff0c;Docker本来只是dotCloud公司的内部项目&#xff0c;其公司创始人 Solomon Hykes 发了一个内部项目&#xff0c;而这个项目就是Docker&#xff0c;自从2013年docker开源以后&#xff0c;在世界范围引起相当轰…

【设计模式】JAVA Design Patterns——Bridge(桥接模式)

&#x1f50d;目的 将抽象与其实现分离&#xff0c;以便二者可以独立变化。 &#x1f50d;解释 真实世界例子 考虑一下你拥有一种具有不同附魔的武器&#xff0c;并且应该允许将具有不同附魔的不同武器混合使用。 你会怎么做&#xff1f; 为每个附魔创建每种武器的多个副本&…

Android 性能为王时代SparseArray和HashMap一争高下

文章目录 一、SparseArray 源码分析1. **类定义和构造函数**2. **基本方法**2.1 put(int key, E value)2.2 get(int key)2.3 delete(int key)2.4 removeAt(int index)2.5 gc()2.6 size()2.7 keyAt(int index) 和 valueAt(int index) 3. **辅助方法**3.1 binarySearch() 二、使用…

Axure软件安装教程

链接&#xff1a;https://pan.baidu.com/s/1fHrSrZ7PIeDZZpn6QyJ6jQ?pwdb4mv 提取码&#xff1a;b4mv 安装完后点击Finish 名字随便起 关闭Axure 复制到安装目录下 最后成果

SQL学习小记(一)

SQL学习小记&#xff08;一&#xff09; 1. 存储过程&存储函数1.1. 存储过程1.2. 存储函数 2. DEFINER3. INSERT INTO&#xff08;插入新记录&#xff09;4. REPLACE()…AS…5. SUM()函数6. CASE WHEN7. STR_TO_DATE日期时间处理函数8. SUBSTRING函数9. dateFormat函数10. …