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

news2024/12/23 13:32:01

双指针篇

    • 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

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

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

相关文章

支持可视化提取变量,Apipost配置变量不要太简单

在调试接口时我们需要将响应结果中的某个字段配置为环境变量在其他接口中引用&#xff0c;之前在Apipost中需要配置脚本而在最近Apipost后执行操作中可以进行可视化的断言和变量提取&#xff0c;无需配置繁琐脚本。 这里我们在登录接口下配置一条Token环境变量&#xff0c;在后…

【百度PARL】强化学习笔记

文章目录 强化学习基本知识一些框架Value-based的方法Q表格举个例子 强化的概念TD更新 Sarsa算法SampleSarsa Agent类 On_policy vs off_policy函数逼近与神经网络DQN算法DQN创新点DQN代码实现model.pyalgorithm.pyagent.py总结&#xff1a;举个例子 实战 视频&#xff1a;世界…

scrapy的入门和使用

scrapy的入门使用 学习目标&#xff1a; 掌握 scrapy的安装应用 创建scrapy的项目应用 创建scrapy爬虫应用 运行scrapy爬虫应用 scrapy定位以及提取数据或属性值的方法掌握 response响应对象的常用属性 1 安装scrapy 命令:     sudo apt-get install scrapy 或者&#x…

使用令牌桶和漏桶实现请求限流逻辑

实现请求限流 令牌桶算法原理实现案例案例目的:实例demo运行结果: 漏桶算法原理:实现案例:案例目的:案例代码运行结果: 令牌桶算法和漏桶算法是两种常用的限流算法&#xff0c;用于控制系统对请求或数据的访问速率。下面分别详细解释这两种算法的原理. 令牌桶算法 原理 令牌桶…

二进制枚举算法

二进制 : 也就是只有0和1的进制表示 ; 二进制枚举算法 一个二进制数 x 可以表示 S 的一个子集&#xff0c;某个二进制位i上为0表示没有选i元素&#xff0c;为1表示选了该元素放入子集,比如13为1101就表示选了0,2,3号元素;对于一个长度为N的序列(也就是包含N个元素)有2^N个子…

深入理解PyTorch中的Hook机制:特征可视化的重要工具与实践

文章目录 一、前言1. 特征可视化的重要性2. PyTorch中的hook机制简介 二、Hook函数概述1. Tensor级别的hook&#xff1a;register_hook()2. Module级别的hook 三、register_forward_hook()详解1. 功能与使用场景2. 示例代码与解释3. 在特征可视化中的具体应用 四、register_bac…

数据结构--图(更新ing~)

树具有灵活性&#xff0c;并且存在许多不同的树的应用&#xff0c;但是就树本身而言有一定的局限性&#xff0c;树只能表示层次关系&#xff0c;比如父子关系。而其他的比如兄弟关系只能够间接表示。 推广--- 图 图形结构中&#xff0c;数据元素之间的关系是任意的。 一、图…

C语言快速排序算法以及代码

接下来我们将用图像模拟来一步步演示快速排序的过程&#xff0c;这样我们将会通过视觉和大脑一起来梳理快速排序的思路。 后文示例的C语言代码将实现图像模拟的过程。 一、图像模拟 快速排序 过程 我们选取十个数字0~9当做我们的排序数字&#xff0c;并将其打乱。然后我们将…

Axure的交互以及情形的介绍

一. 交互 1.1 交互概述 通俗来讲就是&#xff0c;谁用了什么方法做了什么事情&#xff0c;主体"谁"对应的就是axure中的元件&#xff0c;"什么方法"对应的就是交互事件&#xff0c;比如单击事件、双击事件&#xff0c;"什么事情"对应的就是交互…

银河麒麟v10 安装mysql 8.35

银河麒麟v10 安装mysql 8.35 1、下载Mysql安装包2、安装Mysql 8.352.1、安装依赖包2.2、安装Mysql2.3、安装后配置 1、下载Mysql安装包 访问官网下载链接 链接: https://dev.mysql.com/downloads/mysql/ 选择如下 点击下载按钮 下载安装包 2、安装Mysql 8.35 官方安装文档…

挑战52天学小猪佩奇笔记--day25

52天学完小猪佩奇--day25 ​【本文说明】 本文内容来源于对B站UP 脑洞部长 的系列视频 挑战52天背完小猪佩奇----day25 的视频内容总结&#xff0c;方便复习。强烈建议大家去关注一波UP&#xff0c;配合UP视频学习。 day25的主题&#xff1a;生病了 猜台词&#xff1a; Daddy: …

我勒个豆,怎么没人告诉我这个偷懒神器啊

OMG&#xff0c;还有行政人不知道它的吗&#xff1f;&#xff1f;再不用真的亏大了啊&#xff01;&#xff01; 这东西写啥都可以&#xff0c;只有输入需求马上就写好了啊&#xff0c;什么工作总结&#xff0c;活动策划方案&#xff0c;会议纪要啥啥都可以&#xff0c;全能写啊…

持续集成交付CICD:K8S 通过模板文件自动化完成前端项目应用发布

目录 一、实验 1.环境 2.GitLab 更新deployment文件 3.GitLab更新共享库前端项目CI与CD流水线 4.K8S查看前端项目版本 5.Jenkins 构建前端项目 6.Jenkins 再次构建前端项目 二、问题 1. Jenkins 构建CI 流水线报错 2. Jenkins 构建CI 流水线弹出脚本报错 3. Jenkins…

长短期记忆(LSTM)神经网络-多输入分类

目录 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 亮点与优势&#xff1a; 二、实际运行效果&#xff1a; 三、部分程序&#xff1a; 四、完整程序下载&#xff1a; 一、程序及算法内容介绍&#xff1a; 基本内容&#xff1a; 本代码基于Matlab平台编译&am…

Linux-----17、软件包管理

# 软件包管理 # 1、软件包分类 # ㈠ 软件包类型 二进制包源码包 # ① 二进制包 什么是二进制包&#xff1f;有什么特点&#xff1f; 二进制包&#xff0c;指的是已经 1 好了的软件包&#xff0c;只需要直接安装就可以使用。二进制包&#xff0c;不需要编译&#xff0c;直接…

【人工智能革命】:AIGC时代的到来 | 探索AI生成内容的未来

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; IT杂谈 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. AIGC 技术的概述和发展趋势1.1 AIGC 技术的概述1.2 AIGC 技术的发展趋势 二. AIGC 与元宇…

Java-基础部分(二)

一、抽象类 当编写一个类时&#xff0c;我们往往会为该类定义一些方法&#xff0c;这些方法是用来描述该类的行为方式&#xff0c;那么这些方法都有具体的方法体。 分析事物时&#xff0c;发现了共性内容&#xff0c;就出现向上抽取。会有这样一种特殊情况&#xff0c;就是功…

使用 React 实现自定义数据展示日历组件

目录 背景实现日历组件父组件数据 效果最后 背景 项目中需要实现一个日历组件&#xff0c;并且需要展示月&#xff0c;日所对应的数据&#xff08;因为项目需求问题&#xff0c;就不统计年数据总量&#xff09;。网上找了一堆&#xff0c;基本都不大符合项目需求&#xff0c;且…

计算机提示由于找不到vcruntime140_1.dll怎么办,那种修复方法推荐

首先&#xff0c;让我们来了解一下vcruntime140_1.dll是什么。其实&#xff0c;vcruntime140_1.dll是Visual C Redistributable Packages的一部分&#xff0c;它是由Microsoft Visual Studio编写的程序运行时库。它包含了许多用于运行Windows应用程序的函数和资源。因此&#x…

VueStu02-创建一个Vue实例

一、核心步骤 1.准备容器 准备一个盒子div。 2.引包 从官网引包&#xff0c;有开发版本和生产版本之分。 3.创建Vue实例 创建一个Vue实例&#xff0c;new Vue()。 4.指定配置项 指定配置项&#xff0c;用于渲染数据 。 el&#xff1a;指定挂载点。知道自己将来要管理的是…