图解 LeetCode 算法汇总——双指针

news2024/9/25 23:12:05

双指针算法是一种比较常用于搜索链表或数组相关的问题,很多算法的基本的解题思路就是使用暴力搜索法。而双指针是对暴力搜索的一种优化,通过双指针可以减少数据的遍历次数。通常双指针是有两个指针,叫做 light 左指针和 right 右指针,或者叫做快指针和慢指针

  • 作为左右指针的话,一般是在数组的或者链表的头尾两侧,从两遍往中间收缩,获取到符合条件的答案。
  • 作为快慢指针的话,主要应用于解决链表问题。通常快指针移动的比慢指针移动的快,这种方法可以用来检测链表中是否有环、寻找链表的中间结点。

LeetCode 题解

11.盛最多水的容器

题目描述

解题思路

这题可以暴力破解法,双循环遍历出来,查出所有存在的情况,但是时间复杂是O(N²),实现简单,但是比较耗时。而且本题也无需遍历所有的情况,分析一下解题思路:

本题求解的是最大的盛水面积,盛水面积是由宽和高组成,也就是找到横坐标的长度 * 两条竖线中更端的线的乘积。

最开始时候,左右指针分别指向数组的左右两端,获取到容量 min(1,7) * 8。

然后两遍指针往中间收缩,需要往中间移动一个指针,重点是需要移动哪一个?往中间收缩,宽度一定是变短,而高度是由两条竖线中的最短的一条决定。移动更大竖线的指针,面积肯定会减少,因为宽度和高度都在减少,所以需要移动竖线更小的指针,面积才可能增加。上面移动左边的竖线。面积由原来的 min(1,7) * 8 = 8 到 min (8,7) * 7 = 49,面积增多了。

使用 max 变量记录当前最大的面积,和每次搜索的面积做对比,获取到最大值。代码如下所示:

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

        }
        return max;
    }
}

15.三数之和

题目描述

解题思路 for + 双指针

无论是两数之和或者三数之和都可以使用到双指针,但是双指针只有两个指针无法同时记录三个数,所以就需要使用一个 for 循环,for 每次遍历记录一个值,再使用双指针记录左右两个值。

为了减少遍历的次数,需要对数组做一个排序。然后 for 循环定位到第一个元素,左右两个指针的目标值就是 target - for 循环定位元素。左右指针相加得到总和 sum。

  • 如果sum < target,左指针往右移动。
  • 如果sum > target,右指针往左移动。
  • 如果sum = target,符合条件,返回值。

然后定位到第二个元素,继续使用双指针收缩遍历。

代码如下:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> lists = new ArrayList<>();
        Arrays.sort(nums);
	//for循环 + 双指针
	for (int i = 0; i < nums.length; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
	    int target = -nums[i];
	    int left = i +1,right = nums.length - 1;
            while (left < right) {
		int sum = nums[left] + nums[right];
		if (sum == target) {
		    List<Integer> list = new ArrayList<>();
	            list.add(nums[i]);
		    list.add(nums[left]);
		    list.add(nums[right]);
		    lists.add(list);
		    break;
		} else if (sum < target) {
		    left++;
		} else {
		    right--;
		}
	}
	}
	return lists;
    }
}

142. 环形链表 II

题目描述

解决方案

这道题在链表那篇文章也有,求解使用了 hash 表,遍历链表,存储在 hash 表中。如果有相同的数据,说明链表是有环了。本题采用快慢指针的办法。

起始的时候,快慢指针都在首节点。

慢指针一次走一步,快指针一次走两步,移动第一次之后。

fast 指针走过链表末端,说明链表无环,此时直接返回 null。如果两个指针遇上,说明链表有环,当两个指针第一次相遇时,fast 走的步数是 slow 的两倍。

从相遇点到入环点的距离加上 n−1 圈的环长,恰好等于从链表头部到入环点的距离。当 slow 和 fast 相遇时,可以在使用一个额外的指针 ptr,开始指向链表头部,随后它和 slow 每次往后移动,最后他们会在入环结点相遇,此时就能获取到入环结点

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null) {
            return null;
        }
        ListNode slow = head, fast = head;
        while (fast != null) {
            slow = slow.next;
            if (fast.next != null) {
                fast = fast.next.next;
            } else {
                return null;
            }
            if (fast == slow) {
                ListNode ptr = head;
                while (ptr != slow) {
                    ptr = ptr.next;
                    slow = slow.next;
                }
                return ptr;
            }
        }
        return null;
    }
}

总结

双指针算法是一种常用于解决数组或链表相关问题的算法技巧。该算法通常涉及到使用两个指针(索引),它们可以从数组或链表的不同位置出发,根据问题的要求,以一定的方式移动这些指针,从而在数组或链表上执行一些特定的操作。一般使用左右指针和快慢指针两种方式。

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

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

相关文章

redis 核心数据结构

一、简述 redis是一个开源的使用C语言编写的一个kv存储系统&#xff0c;是一个速度非常快的非关系远程内存数据库。它支持包括String、List、Set、Zset、hash五种数据结构。 除此之外&#xff0c;通过复制、持久化和客户端分片等特性&#xff0c;用户可以很方便地将redis扩展…

Ansys Zemax | 如何建立二向分色分光镜

分光镜(Beam splitter)可被运用在许多不同的场合。一般而言&#xff0c;入射光抵达二向分色分光镜(dichroic beam splitter)时&#xff0c;会根据波长的差异产生穿透或反射的现象。这篇文章将说明如何在OpticStudio的非序列模式(non-sequential mode)中建立二向分色分光镜&…

IT技术总监的成长之路

目录 1.CIO之说 2.新职业机会的出现 3.IT主管的两个发展机会 4.七分管理三分技术的CIO 5.七分技术三分管理的CTO 6.CIO的职业规划要求 6.1. 企业战略管理 6.2.信息资源规划 6.3.生产过程管理 6.4. 项目管理 6.5.物流管理 6.6.网络规划与建设 6.7.信息安全技术 6.…

zabbix网络管理安装教程

安装&#xff1a; apt install zabbix-server-mysql zabbix-frontend-php zabbix-nginx-conf zabbix-sql-scripts zabbix-agent 参考资源&#xff1a; 官网&#xff1a; 下载&#xff1a; 其它&#xff1a; 常用指令&#xff1a; 目标与应用价值&#xff1a; 部署难点&#…

友思特新闻|友思特与IDS深化战略合作伙伴关系

尊敬的客户和合作伙伴&#xff0c; 我们非常高兴地宣布&#xff0c;友思特已经与国际领先的机器视觉解决方案提供商 IDS 深化了我们的合作关系。 作为 IDS 的长期合作伙伴&#xff0c;友思特一直致力于为国内客户提供最先进的机器视觉技术和解决方案。 自从友思特与 IDS 合作…

新的~

我昨天加班解决一个概率性出现的bug&#xff0c;这个概率性的问题先介绍下。 の如果正常开机上电&#xff0c;ADC是可以正常工作的&#xff0c;出现问题的时候会开机概率性出现ADC工作不正常&#xff0c;如果工作不正常&#xff0c;重新配置寄存器也不会正常。 の如果开机后ADC…

Ansys Zemax | 光学系统设计中如何使用玻璃替换方法来优化玻璃

在光学系统中选择最优玻璃材料时&#xff0c;Conrady d-D以及模型玻璃等传统的玻璃选择方法提供的帮助有限。本文介绍了如何使用玻璃替换方法进行直接玻璃优化&#xff0c;以及在考虑玻璃的可用性、成本及耐候性等因素时&#xff0c;如何进一步严格挑选玻璃。 简介 玻璃替换方法…

node绿色版本升级

node绿色版本升级 安装绿色版本&#xff1a; 1.非管理员没有安装软件的权限&#xff0c;因此不能直接使用安装包&#xff0c;因此想到了使用绿色版本 2.之前已安装一个版本&#xff0c;因此环境变量的设置已经完成 直接下载绿色的版本&#xff0c;找到之前的安装位置&#xff0…

FX3U PLC高速计数器(摆杆编码器角度测量梯形图代码)

FX3U的高速计数器接线和基本配置,请查看下面文章链接: 三菱FX3U PLC高速计数器应用(附代码)_三菱高速计数器的使用_RXXW_Dor的博客-CSDN博客本文主要以三菱FX3U系列的高速计数为例来讲解,我们简单的看下三菱的编程手册对高速计数器的描述,工业现场建议大家采用AB双向计数…

Gitlab----Shell类型的gitlab-runer设置以root权限执行

【原文链接】Gitlab----Shell类型的gitlab-runer如何设置以root权限执行 1 编辑修改 /etc/systemd/system/gitlab-runner.service 文件&#xff0c;将 --user 修改为 root 2 重启服务 执行如下命令重启 gitlab-runer 服务 systemctl daemon-reload systemctl restart gitlab…

C++项目中mysql的环境配置

第一步创建好项目&#xff0c;选择X64架构 此次项目采用动态库在项目文件夹加入mysql的库分别为libmysql.dll和include 在包含目录中填入相对路径 添加附加依赖项 现在我们写一个开发环境验证代码&#xff0c;检查一下环境是否配置成功 F7生成此时完美运行 至此环境已经配置完成…

VR+中医骨伤学仿真情景实训教学|英途信息

首先&#xff0c;VR骨伤学虚拟实训教学可以突破地域限制。传统的实训教学需要学生亲身前往实地进行观察学习&#xff0c;但这常常受到时间、地点和费用等方面的限制。而通过虚拟现实技术&#xff0c;学生只需佩戴VR头盔&#xff0c;便可随时随地进行学习和实训&#xff0c;无需…

序列化和反序列化:将数据变得更加通用化

序列化与反序列化简介 序列化和反序列化是计算机领域中常用的概念&#xff0c;用于将对象或数据结构转换为字节序列&#xff08;序列化&#xff09;和将字节序列转换回对象或数据结构&#xff08;反序列化&#xff09;。 序列化是指将对象或数据结构转换为字节序列的过程。通…

Git使用方法与IDEA集成Git

1.Git介绍 1.1版本控制(理解) 无论是代码编写&#xff0c;还是文档编写&#xff0c;我们都会遇到对文档内容反复修改的情况。 1.2开发中存在的问题(理解) 程序员小明负责的模块就要完成了&#xff0c;就在即将提交发布之前的一瞬间&#xff0c;电脑突然蓝屏&#xff0c;硬盘…

使用RNN联合注意力机制实现机器翻译

https://zhuanlan.zhihu.com/p/28834212 具体来自这一篇文章的指导 一、相关使用的查漏补缺&#xff1a; 1.其中的两种神奇的处理字符的操作&#xff1a; 2.关于nn.GRU()的参数解释和用法&#xff1a; http://t.csdn.cn/30PZL 这篇文章讲得很清楚&#xff0c;需要用来预测…

windows下mysql的高可用方案

PS:理论上linux下也可以使用这种方案 环境准备&#xff1a; 首先准备两台电脑&#xff0c;全部安装MySQL&#xff0c;然后分别查看一下ip地址&#xff0c;我的两个ip分别是&#xff1a; 192.168.25.134&#xff08;简称134&#xff09; 192.168.25.135&#xff08;简称135&a…

亚马逊日本站养号测评需要哪些资源和注意点,如何确保账号的稳定性和纯净环境?

日本亚马Amazon.co.jp逊简称日亚&#xff0c;在日本国内亚马逊是アマゾン&#xff0c;日本亚马逊是美国亚马逊在日本成立的分公司&#xff0c;于2000年开通。 目前亚马逊日本站的情况是&#xff0c;流量大&#xff0c;产品少。有很多美国的卖家之间把亚马逊北美站的热卖产品加…

malloc是如何实现内存分配的?【深入理解】

文章目录 前言一、malloc实现原理概括&#xff1f;二、brk() 函数与mmap()函数三、mmap实现原理普通读写与mmap对比mmap内存映射实现过程mmap 的适用场景 前言 在C和C中&#xff0c;malloc函数是用于动态分配内存的常用函数。本文将深入探究malloc函数的内存分配实现机制&…

Linux 定时任务Crontab详解及常见问题解决

Linux 定时任务Crondtab简单了解 crond 是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程&#xff0c;与windows下的计划任务类似&#xff0c;当安装完成操作系统后&#xff0c;默认会安装此服务 工具&#xff0c;并且会自动启动crond进程&#xff0c;cron…

Python 变量作用域

视频版教程 Python3零基础7天入门实战视频教程 在程序中定义一个变量时&#xff0c;这个变量是有作用范围的&#xff0c;变量的作用范围被称为它的作用域。根据定义变量的位置&#xff0c;变量分为两种。 局部变量。在函数中定义的变量&#xff0c;包括参数&#xff0c;都被称…