Leetcod面试经典150题刷题记录 —— 双指针篇

双指针篇

    • 1. 验证回文串
      • Python3
    • 2. 判断子序列
      • Python3
        • 双指针
    • 3. 两数之和 II - 输入有序数组
      • Python3
    • 4. 盛最多水的容器
      • Python3
        • 双指针
    • 5. 三数之和

1. 验证回文串

题目链接:验证回文串 - leetcode
题目描述:
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
题目归纳:
和传统的回文串验证不一样,有一些非(字母数字)字符,不过大致思路一样。

解题思路:
(1) 解法一: 见代码。

Python3

class Solution:
    def isPalindrome(self, s: str) -> bool:
        n = len(s)
        left, right = 0, n-1
        while left < right:
            while left < right and not s[left].isalnum(): # 跳过非(字母数字)字符
                left += 1
            while left < right and not s[right].isalnum():# 跳过非(字母数字)字符
                right -= 1
            if left < right:
                if s[left].lower() != s[right].lower(): # 有不一样则return False
                    return False
                left += 1
                right -= 1
        
        return True # 遍历结束代表是这个题目说的回文串

2. 判断子序列

题目链接:判断子序列 - leetcode
题目描述:
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
题目归纳:
注意,是子序列,而不是子串。子序列可以间隔跳跃,子串必须是连续的。

解题思路:
(1) 解法一: 双指针。一个一个比较,直到s或t任意一方遍历到末尾,最后若遍历s的指针到达了末尾,则说明s是t的子序列,否则不是。
(2) 解法二: 动态规划。略,时间复杂度和空间复杂度都不如双指针,请看官方题解。

Python3

双指针

时间复杂度: O ( n + m ) O(n+m) O(n+m),其中 n n n s s s 的长度, m m m t t t 的长度。每次无论是匹配成功还是失败,都有至少一个指针发生右移,两指针能够位移的总距离为 n + m n+m n+m
空间复杂度: O ( 1 ) O(1) O(1)

class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        # 双指针解法,注意:判断s是否是t的子序列
        # 贪心匹配,匹配位置更前的字符即可
        i = 0 # s指针
        j = 0 # t指针
        while i < len(s) and j < len(t): # 有j+=1,循环一定能跳出
            # (1)匹配成功,同时右移
            if s[i] == t[j]:
                i += 1
                j += 1
            # (2)匹配成功或失败,t指针都右移
            else:
                j += 1

        # (3)若i到达了s字符串末尾,则匹配完成,返回true
        if i == len(s):
            return True
        else:
            return False

3. 两数之和 II - 输入有序数组

题目链接:两数之和 II - 输入有序数组 - leetcode
题目描述:
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。你所设计的解决方案必须只使用常量级的额外空间。
题目归纳:
(1) 数组非递减。
(2) 数组元素可能有正负,target也可能有正负。
(3) 最终返回结果是,一个数组,但只有两个元素值。
(4) 每个输入答案唯一。
(5) 常量级别的空间。看到这种条件一般多是双指针或者多指针解法。

解题思路:
(1) 解法一: 二分查找,时间复杂度不如双指针,请看官方题解。
(2) 解法二: 双指针。只要numbers[left] + numbers[right] < target,left就往右加,反之若numbers[left] + numbers[right] > target,right就往左减,为什么这样可以?因为最终答案一定在数组的边界以内,之所以会有困扰,肯定是因为在数学上理解 x + y = t a r g e t x + y = target x+y=target,画下这个函数的直线,从 x + y < t a r g e t x + y < target x+y<target的区域出发,会有两个方向可以落到 x + y = t a r g e t x + y = target x+y=target直线上,分别是 x x x正半轴方向与 y y y正半轴方向。具体的可以看官方题解。

Python3

class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        left, right = 0, len(numbers) - 1
        while left < right:
            sum = numbers[left] + numbers[right]
            if (sum == target):
                return [left+1, right+1]
            elif sum < target:
                left += 1 # 最终left是不断相加,到达目标点,不要考虑left可能存在--情况
            else:
                right -= 1 # 最终right是不断相减,到达目标点,不要考虑right可能存在++情况
        
        return [-1,-1]

4. 盛最多水的容器

题目链接:盛最多水的容器 - leetcode
题目描述:
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。说明:你不能倾斜容器。
water container
题目归纳:
(1) 水的高度最多到低的槽板。
(2) 更高的槽板不能动,要尽可能的把更低的槽板通过移动换掉。
(3) 水量公式 c a p a c i t y = ( r − l + 1 ) ∗ m i n ( h e i g h t [ l ] , h e i g h t [ r ] ) capacity = (r-l+1) * min(height[l], height[r]) capacity=(rl+1)min(height[l],height[r]),即宽度*高度。
(4) 记录历史最大水量值 m a x c a p a c i t y max_capacity maxcapacity

解题思路:
(1) 解法: 双指针。

Python3

双指针
class Solution:
    def maxArea(self, height: List[int]) -> int:
        # 双指针解法
        max_capacity = 0
        n = len(height)
        l, r = 0, n-1
        while l < r:
            # 求当前容量
            capacity = (r - l) * min(height[l], height[r])
            # 记录历史最大容量
            max_capacity = max(capacity, max_capacity)
            # 移动高度低的一方
            if(height[l] <= height[r]):
                l += 1
            else:
                r -= 1

        return max_capacity

5. 三数之和

题目链接:三数之和 - leetcode
题目描述:
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。
题目归纳:
(1) i ≠ j , i ≠ k , j ≠ k i \neq j, i \neq k, j \neq k i=j,i=k,j=k
(2) n u m s [ i ] + n u m s [ j ] + n u m s [ k ] = 0 nums[i] + nums[j] + nums[k] = 0 nums[i]+nums[j]+nums[k]=0
(3) 找到所有这样的 n u m s [ i ] , n u m s [ j ] , n u m s [ k ] nums[i], nums[j], nums[k] nums[i],nums[j],nums[k]三元组,并将其作为数组返回。
(4) 输出的顺序和三元组的顺序并不重要。也就是说, ( a , b , c ) (a,b,c) (a,b,c) ( a , c , b ) (a,c,b) (a,c,b)是同样的三元组,那不如假设返回的三元组一定满足 a ≤ b ≤ c a \le b \le c abc。因此涉及到了排序。
(题外) 假设 n u m s [ i ] = a nums[i] = a nums[i]=a是已知的,那么就变成了在两个有序数组(都是nums)中寻找 n u m s [ j ] = b 、 n u m s [ k ] = c nums[j] = b、nums[k] = c nums[j]=bnums[k]=c满足 b + c = − a b+c=-a b+c=a,这里再看到上面的第3题 两数之和 II - 输入有序数组,熟悉的感觉来了,就回归到了 t a r g e t = − a target=-a target=a,数组为排序后的 n u m s [ i : ] nums[i:] nums[i:],而之所以不这样做,是因为,这样会产生 ( a , b , c ) (a,b,c) (a,b,c) ( a , c , b ) (a,c,b) (a,c,b)这样的三元组,在这道题中,这样是重复的。

解题思路:
(1) 解法: 排序+双指针。来自官方解答。

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        nums.sort()
        ans = list()

        # 枚举 a
        for i in range(n): # 循环(1)
            # 需要和上一次枚举的数不相同,若相同则下一轮循环
            if i > 0 and nums[i] == nums[i-1]:
                continue
            # c 对应的指针初始指向数组的最右端
            k = n - 1
            target = -nums[i]
            # 枚举 b
            for j in range(i+1, n): # 循环(2)
                # 需要和上一次枚举的数不相同,若相同则下一轮循环
                if j > i+1 and nums[j] == nums[j-1]:
                    continue
                # j<k:保证 b 的指针在 c 的指针的左侧
                while j < k and nums[j] + nums[k] > target:
                    k -= 1
                # 不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
                if j == k:
                    break
                if nums[j] + nums[k] == -nums[i]:
                    ans.append([nums[i], nums[j], nums[k]])
        return ans

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Cloud + Vue前后端分离-第6章 通用代码生成器开发

Spring Cloud Vue前后端分离-第6章 通用代码生成器开发 6-1 代码生成器原理介绍 1.增加generator模块&#xff0c;用于代码生成 2.集成freemarker 通用代码生成器开发 FreeMarker 是一款模版引擎&#xff0c;通过模板生成文件&#xff0c;包括html页面&#xff0c;excel …

基于vue+element-plus+echarts制作动态绘图页面(柱状图,饼图和折线图)

前言 我们知道echarts是一个非常强大的绘图库&#xff0c;基于这个库&#xff0c;我们可以绘制出精美的图表。对于一张图来说&#xff0c;其实比较重要的就是配置项&#xff0c;填入不同的配置内容就可以呈现出不同的效果。 当然配置项中除了样式之外&#xff0c;最重要的就是…

腾讯云debian服务器的连接与初始化

目录 1. 远程连接2. 软件下载3. 设置开机自启动 1. 远程连接 腾讯云给的服务器在安装好系统之后&#xff0c;只需要在防火墙里面添加一个白名单&#xff08;ip 或者域名&#xff09;就能访问了。 防火墙添加本机WLAN的IPv4白名单&#xff0c;本地用一个远程工具连接&#xff…

C++设计模式之——命令模式

命令模式 概念创建步骤示例示例一代码实现运行结果 示例二代码实现运行结果 示例三示例代码运行结果 示例四代码实现运行结果 应用场景 概念 命令模式是一种行为型设计模式&#xff0c;它允许将请求封装为一个对象&#xff0c;从而使得可以参数化客户端请求、将请求排队或者记…

npm login报错:Public registration is not allowed

npm login报错:Public registration is not allowed 1.出现场景2.解决 1.出现场景 npm login登录时,出现 2.解决 将自己的npm镜像源改为npm的https://registry.npmjs.org/这个&#xff0c;解决&#xff01;

安防视频云平台/可视化监控云平台EasyCVR获取设备录像失败,该如何解决?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。GB28181音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视…

打响指针的第一枪:指针家族

前言 指针其实是我们学习C语言中最难的知识点&#xff0c;很多人在学习指针的时候会被绕晕&#xff0c;包括博主也是&#xff0c;当初百思不得其解&#xff0c;脑袋都要冒烟了&#xff0c;本来打算在学习指针的时候就写一篇博客&#xff0c;但是当初自己的能力还是没有办法去完…

harmonyOS 自定义组件基础演示讲解

上文 HarmonyOS组件属性控制 链式编程格式推荐我们讲了一些系统组件 可以传入一些事件和参数 来达到一些不同的效果 其实 我们还可以用自己写的组件 那么 组件这么写&#xff1f; 其实 我们的 page 内部结果 就是一个组件 harmonyOS的概念 万物皆组件 那么 我们就可以在他下面…

低代码软件开发的革命

一、前言 如果一个概念能在科技圈火起来&#xff0c;它往往兼具字面简明和内涵丰富的特征&#xff0c;并具有某种重塑产业格局的潜力。低代码&#xff08;Low Code&#xff09;就是这样一个典型。顾名思义&#xff0c;低代码是指少用代码&#xff0c;甚至不用代码&#xff0c;仅…

自动化测试 (五) 读写64位操作系统的注册表

自动化测试经常需要修改注册表 很多系统的设置&#xff08;比如&#xff1a;IE的设置&#xff09;都是存在注册表中。 桌面应用程序的设置也是存在注册表中。 所以做自动化测试的时候&#xff0c;经常需要去修改注册表 Windows注册表简介 注册表编辑器在 C:\Windows\regedit…

Netty入门基础知识

简介 Netty是一款高性能java网络编程框架&#xff0c;被广泛应用在中间件、直播、社交、游戏等领域。Netty对java NIO进行高级封装&#xff0c;简化了网络应用的开发过程。 stream与channel stream不会自动缓冲数据&#xff0c;channel会利用系统提供的发送缓冲区&#xff0c;接…

科创金融的向善力量:浙商银行多措并举赋能科创企业,打造科技金融服务生态圈

近日&#xff0c;浙商银行科技金融服务发布会在杭州举行。 发布会以“智汇科创&#xff0c;善行未来”为主题&#xff0c;围绕科技金融服务“向善”新生态&#xff0c;浙商银行重磅推出科创企业全图景服务方案&#xff0c;正式发布科创积分贷&#xff0c;与浙江大学联合发布人…

初冬天气变化大,长辈身上的这些小毛病千万不能轻视

心率、血氧、肺功能&#xff0c;甚至是一次次不起眼的咳嗽&#xff0c;背后都可能藏着健康问题。但是我们可以利用好手表上的健康检测功能&#xff0c;提前获知健康数据的变化&#xff0c;有的放矢&#xff0c;科学应对身体的不适&#xff0c;度过一个有准备的温暖冬天&#xf…

【JVM从入门到实战】(七)Java内存区域

运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域&#xff0c;称之为运行时数据区。 《Java虚拟机规范》中规定了每一部分的作用 线程不共享&#xff1a;程序计数器、虚拟机栈、本地方法栈 线程共享&#xff1a;方法区&#xff0c;堆 1. 程序计数器(Program Count…

定位咨询:企业市场竞争中的定海神针

什么是定位咨询?定位咨询能给企业带来什么帮助?在现代市场的激烈竞争中&#xff0c;定位咨询不仅是企业区分自己的重要工具&#xff0c;更是它们赢得市场份额的关键。以下是定位咨询的定义和几个核心方面&#xff0c;笔者将列举具体案例说明其重要性和实用性。 定位咨询的简单…

kafka文件存储机制

Topic分为好几个partition分区&#xff0c;每个分区对应于一个log文件&#xff0c;log文件其实是虚的&#xff0c;Kafka采取了分片和索引机制&#xff0c; 将每个partition分为多个segment&#xff08;大小为1G&#xff09;。每个segment包括&#xff1a;“.index”文件、“.lo…

SiLM5350MDBCA-DG车规级隔离驱动芯片,我们能为汽车智能提供什么?

SiLM5350MDBCA-DG是一款适用于IGBT、MOSFET的单通道 隔离门极驱动器&#xff0c;具有10A拉电流和10A灌电流驱动能 力。提供内部钳位功能&#xff0c;可单独控制 上升时间和下降时间。 在 SOP8 封 装 中 具 有 3000VRMS 隔 离 耐 压 &#xff08; 符 合 UL1577&#xff09;。 与…

API资源对象StorageClass;Ceph存储;搭建Ceph集群;k8s使用ceph

API资源对象StorageClass;Ceph存储;搭建Ceph集群;k8s使用ceph API资源对象StorageClass SC的主要作用在于&#xff0c;自动创建PV&#xff0c;从而实现PVC按需自动绑定PV。 下面我们通过创建一个基于NFS的SC来演示SC的作用。 要想使用NFS的SC&#xff0c;还需要安装一个NFS…

SMART PLC多路复用器功能块

SMART PLC指针应用介绍: https://rxxw-control.blog.csdn.net/article/details/123890483https://rxxw-control.blog.csdn.net/article/details/123890483SMART PLC指针在配方上的应用 https://rxxw-control.blog.csdn.net/article/details/122090212

CogVLM与CogAgent:开源视觉语言模型的新里程碑

引言 随着机器学习的快速发展&#xff0c;视觉语言模型&#xff08;VLM&#xff09;的研究取得了显著的进步。今天&#xff0c;我们很高兴介绍两款强大的开源视觉语言模型&#xff1a;CogVLM和CogAgent。这两款模型在图像理解和多轮对话等领域表现出色&#xff0c;为人工智能的…