Hot100刷题计划-Day2-滑动窗口、双指针、数组、链表、动态规划

  • LeetCode Hot 100 是最常被考察的题目集合,涵盖了面试中常见的算法和数据结构问题。
  • 刷 Hot100可以让你在有限的时间内集中精力解决最常考的问题。
  • 不仅要写出代码,还要理解问题的本质、优化解法和复杂度分析。

滑动窗口

438. 找到字符串中所有字母异位词

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。s 和 p 仅包含小写字母。

思路: 哈希表+滑动窗口。把待匹配的字符串用数组哈希化,左右指针滑动,右指针纳入元素,判断是否合法,不合法则移动左指针直到合法。若窗口合法,且长度相等,符合条件。

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        ans = []             # 存放结果答案
        cnt = [0] * 26       # 小写字母,26个位置存放频率

        for i in p:
            cnt[ord(i)-ord('a')] += 1   # 待匹配的字符串字符频率

        left = 0
        for right in range(len(s)):
            cnt[ord(s[right])-ord('a')] -= 1       # 右指针位置元素纳入窗口

            while cnt[ord(s[right])-ord('a')] < 0:   # 若有元素频率小于0,①不在待匹配字符串,②多次出现同一字符【都是有字符超了】
                cnt[ord(s[left])-ord('a')] += 1      # 将左指针对应的元素释放,频率还回去
                left += 1                            # 左指针右移,左指针追右指针
            
            if right - left + 1 == len(p):          # 如果长度相等,加上前面都不小于0,符合题意
                ans.append(left)
        return ans

209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其总和大于等于 target 的长度最小的 子数组[numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

思路: 依次纳入窗口,判断窗口中子数组是否满足target,因为要找最小长度,满足则移动左指针,更新最小长度。时间复杂度O(n),空间O(1).

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        if sum(nums)<target: return 0  # 不存在符合条件的子数组
        total = 0
        slow = 0
        ans = float('inf')

        for fast in range(len(nums)):  
            total += nums[fast]         # 依次将元素纳入窗口
            while total >= target:        # 找最小数组,满足条件移动左指针
                ans = min(ans, fast-slow+1)  # 更新最小长度
                total -= nums[slow]
                slow += 1
        return ans

76. 最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

注意:

对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。

思路: 记录每个字符需要个数和总个数,不断扩展右边界,直到覆盖全部子串。覆盖全部子串后,再不断缩小左边界,直到找到覆盖的最小区间(其中之一)。记录区间是否需要更新,再缩小一步左边界。

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        need = Counter(t)     # 统计下需要的数出现频率(更新可能出现负数)
        ans = (0, float('inf'))  # 元组记录起始索引和长度
        needcnt = len(t)      # 总需要的数

        left = 0

        for right in range(len(s)):   # 用enumerate()写会好看,扩展窗口
            if need[s[right]] > 0:    # 目标数,则总数减1
                needcnt -= 1
            need[s[right]] -= 1       # 字符记录到对应字典,减1

            if needcnt == 0:          # 满足覆盖的子数组条件
                while True:           # 试图移动左指针,缩小窗口
                    if need[s[left]] == 0:
                        break
                    need[s[left]] += 1  # 不是目标数,则左移左指针
                    left += 1

                if right - left < ans[1] - ans[0]: # 将所有非目标数移除,得到一个最小区间
                    ans = (left, right)            # 如果比之前记录的小,更新
                need[s[left]] += 1     # 移动左指针,同时将needcnt也加个1
                needcnt += 1
                left += 1
        return '' if ans[1]>len(s) else s[ans[0]: ans[1]+1] # 切片用法

链表

142. 环形链表Ⅱ

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

思路: 快指针2步,慢指针1步;快慢指针环中相遇,从相遇点到环入口,和从链表到环入口距离一样。时间复杂度O(n),空间O(1).

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        fast = slow = head   # 使用快慢指针
        
        while fast and fast.next:  # 确保下一个节点存在,否则无法访问其next
            slow = slow.next       # 慢指针每次走一步
            fast = fast.next.next  # 快指针每次走两步

            if fast == slow:        # 快指针在环中追到慢指针
                slow = head        # 重置慢指针的位置
                while fast != slow:
                    slow = slow.next
                    fast = fast.next
                return slow        # 慢指针再次移动的位置即为入环index

递归

78. 子集

思路: 回溯。每次进入回溯函数,先将当前集合加入结果,再遍历该层元素加入,递归回溯。主要起始位置需要变。

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        self.ans = []  # 存放结果
        self.backtracking(nums, 0, [])
        return self.ans

    def backtracking(self, nums, startIndex, path):
        self.ans.append(path[:])  # 每次都想加入结果集
        for i in range(startIndex, len(nums)):
            path.append(nums[i])   # 往里新增该层的元素
            self.backtracking(nums, i+1, path) # 递归进入下一层
            path.pop()

回溯

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

思路: 不同的按键是不同的层,作为参数传递。

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if not digits: return []  # 处理空字符串
        phone_map ={
            '2' : 'abc',
            '3' : 'def',
            '4' : 'ghi',
            '5' : 'jkl',
            '6' : 'mno',
            '7' : 'pqrs',
            '8' : 'tuv',
            '9' : 'wxyz'
        }
        self.ans = []
        self.backtracking(phone_map, digits, 0, [])
        return self.ans

    def backtracking(self, phone_map, digits, startIndex, path):
        if startIndex == len(digits):
            self.ans.append(''.join(path))
            return 
        letters = phone_map[digits[startIndex]]
        for letter in letters: 
            path.append(letter)
            self.backtracking(phone_map, digits, startIndex+1, path)
            path.pop()

39. 组合总和

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

思路:

class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        self.ans = []
        self.backtracking(candidates, target, [], 0)
        return self.ans

    def backtracking(self, candidates, target, path, startIndex): 
        if target == 0:
            self.ans.append(path[:])
            return
        if target < 0:
            return
        
        for i in range(startIndex, len(candidates)):  # 为了避免顺序不同元素相同的重复,还是按顺序选
            path.append(candidates[i])
            self.backtracking(candidates, target-candidates[i], path, i) # 可以被无限选取,所以用i不用i+1
            path.pop()

131. 分割回文串

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

思路: 如果是回文串,则加入path。path长度达到字符串长度,找到一种方案。

class Solution:
    def partition(self, s: str) -> List[List[str]]:
        self.ans = []
        self.backtracking(s, [], 0)
        return self.ans

    def backtracking(self, s, path, startIndex):
        if startIndex >= len(s):         # 超过长度则得到一种分割方法
            self.ans.append(path[:])
            return
        for i in range(startIndex, len(s)):
            if s[startIndex:i+1] == s[startIndex:i+1][::-1]: # 最佳实践,判断是回文串就写入
                path.append(s[startIndex:i+1])
                self.backtracking(s, path, i+1)
                path.pop()
            

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

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

相关文章

Docker Compose 安装 Harbor

我使用的系统是rocky Linux 9 1. 准备环境 确保你的系统已经安装了以下工具&#xff1a; DockerDocker ComposeOpenSSL&#xff08;用于生成证书&#xff09;#如果不需要通过https连接的可以不设置 1.1 安装 Docker 如果尚未安装 Docker&#xff0c;可以参考以下命令安装&…

深入浅出:多功能 Copilot 智能助手如何借助 LLM 实现精准意图识别

阅读原文 1. Copilot中的意图识别 如果要搭建一个 Copilot 智能助手&#xff0c;比如支持 知识问答、数据分析、智能托管、AIGC 等众多场景或能力&#xff0c;那么最核心的就是基于LLM进行意图识别分发能力&#xff0c;意图识别的准确率直接决定了 Copilot 智能助手的能力上限…

ZED-OpenCV项目运行记录

项目地址&#xff1a;GitCode - 全球开发者的开源社区,开源代码托管平台 使用 ZED 立体相机与 OpenCV 进行图像处理和深度感知 • 使用 ZED 相机和 OpenCV 库捕获图像、深度图和点云。 • 提供保存并排图像、深度图和点云的功能。 • 允许在不同格式之间切换保存的深度图和点云…

Linux 常见用例汇总

注&#xff1a;本文为 Linux 常见用例文章合辑。 部分内容已过时&#xff0c;未更新整理。 检查 Linux 上的 glibc 版本 译者&#xff1a;joeren | 2014-11-27 21:33 问&#xff1a;检查 Linux 系统上的 GNU C 库&#xff08;glibc&#xff09;的版本&#xff1f; GNU C 库&…

PHP阶段一

PHP 一门编程语言 运行在服务器端 专门用户开发网站的 脚本后缀名.php 与HTML语言进行混编&#xff0c;脚本后缀依然是.php 解释型语言&#xff0c;不要编译直接运行 PHP运行需要环境&#xff1a; Windows phpstudy Linux 单独安装 Web 原理简述 1、打开浏览器 2、输入u…

REMOTE_LISTENER引发的血案

作者&#xff1a;Digital Observer&#xff08;施嘉伟&#xff09; Oracle ACE Pro: Database PostgreSQL ACE Partner 11年数据库行业经验&#xff0c;现主要从事数据库服务工作 拥有Oracle OCM、DB2 10.1 Fundamentals、MySQL 8.0 OCP、WebLogic 12c OCA、KCP、PCTP、PCSD、P…

Redis篇--常见问题篇6--缓存一致性1(Mysql和Redis缓存一致,更新数据库删除缓存策略)

1、概述 在使用Redis作为MySQL的缓存层时&#xff0c;缓存一致性问题是指Redis中的缓存数据与MySQL数据库中的实际数据不一致的情况。这可能会导致读取到过期或错误的数据&#xff0c;从而影响系统的正确性和用户体验。 为了减轻数据库的压力&#xff0c;通常读操作都是先读缓…

Phono3py hdf5文件数据读取与处理

Phono3py是一个主要用python写的声子-声子相互作用相关性质的模拟包&#xff0c;可以基于有限位移算法实现三阶力常数和晶格热导率的计算过程&#xff0c;同时输出包括声速&#xff0c;格林奈森常数&#xff0c;声子寿命和累积晶格热导率等参量。 相关介绍和安装请参考往期推荐…

机器学习(四)-回归模型评估指标

文章目录 1. 哪个模型更好&#xff1f;2. 线性回归评估指标3. python 实现线性模型评估指标 1. 哪个模型更好&#xff1f; 我们之前已经对房价预测的问题构建了线性模型&#xff0c;并对测试集进行了预测。 如图所示&#xff0c;横坐标是地区人口&#xff0c;纵坐标是房价&am…

Oracle 适配 OpenGauss 数据库差异语法汇总

背景 国产化进程中&#xff0c;需要将某项目的数据库从 Oracle 转为 OpenGauss &#xff0c;项目初期也是规划了适配不同数据库的&#xff0c;MyBatis 配置加载路径设计的是根据数据库类型加载指定文件夹的 xml 文件。 后面由于固定了数据库类型为 Oracle 后&#xff0c;只写…

Unity引擎学习总结------动画控件

左侧窗格可以在参数视图和图层视图之间切换。参数视图允许您创建、查看和编辑动画控制器参数。这些是您定义的变量&#xff0c;用作状态机的输入。要添加参数&#xff0c;请单击加号图标并从弹出菜单中选择参数类型。要删除参数&#xff0c;请在列表中选择该参数并按删除键&…

记录:virt-manager配置Ubuntu arm虚拟机

virt-manager&#xff08;Virtual Machine Manager&#xff09;是一个图形用户界面应用程序&#xff0c;通过libvirt管理虚拟机&#xff08;即作为libvirt的图形前端&#xff09; 因为要在Linux arm环境做测试&#xff0c;记录下virt-manager配置arm虚拟机的过程 先在VMWare中…

VSCode 搭建Python编程环境 2024新版图文安装教程(Python环境搭建+VSCode安装+运行测试+背景图设置)

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。—— 苏轼《水调歌头》 创作者&#xff1a;Code_流苏(CSDN) 目录 一、Python环境安装二、VScode下载及安装三、VSCode配置Python环境四、运行测试五、背景图设置 很高兴你打开了这篇博客&#xff0c;更多详细的安装教程&…

VBA编程:自定义函数 - 字符串转Hex数据

目录 一、自定义函数二、语法将字符串转换为hex数据MID函数:返回一个字符串中指定位置和长度的子串LEN函数:返回一个字符串的长度(字符数)Asc函数三、定义变量和数据类型变量声明的基本语法常见的数据类型四、For循环基本语法五、&运算符一、自定义函数 定义:用户定义…

jvm字节码中方法的结构

“-Xss”这一名称并没有一个特定的“为什么”来解释其命名&#xff0c;它更多是JVM&#xff08;Java虚拟机&#xff09;配置参数中的一个约定俗成的标识。在JVM中&#xff0c;有多个配置参数用于调整和优化Java应用程序的性能&#xff0c;这些参数通常以一个短横线“-”开头&am…

网络架构与IP技术:4K/IP演播室制作的关键支撑

随着科技的不断发展&#xff0c;广播电视行业也在不断迭代更新&#xff0c;其中4K/IP演播室技术的应用成了一个引人注目的焦点。4K超高清技术和IP网络技术的结合&#xff0c;不仅提升了节目制作的画质和效果&#xff0c;还为节目制作带来了更高的效率和灵活性。那么4K超高清技术…

Mac上Stable Diffusion的环境搭建(还算比较简单)

https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Installation-on-Apple-Silicon AI兴起的速度是真的快&#xff0c;感觉不了解点相关的东西都要与时代脱节了&#xff0c;吓得我赶紧找个AIGC看看能不能实现我艺术家的人梦想&#xff08;绷不住了&#xff09; 我…

什么是虚拟机?常用虚拟机软件有哪些?

目录 VMware Workstation Oracle VM VirtualBox Microsoft Hyper-V 虚拟机&#xff08;Virtual Machine&#xff0c;简称VM&#xff09;是一种通过软件模拟的具有完整硬件系统功能的、运行在计算机上的软件。它允许用户在单一物理机器上同时运行多个操作系统&#xff0c;每个…

git branch -r(--remotes )显示你本地仓库知道的所有 远程分支 的列表

好的&#xff0c;git branch -r 这个命令用于列出远程分支。让我详细解释一下&#xff1a; 命令&#xff1a; git branch -rdgqdgqdeMac-mini ProductAuthentication % git branch -rorigin/main作用&#xff1a; 这个命令会显示你本地仓库知道的所有 远程分支 的列表。它不…

Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)

01.生命周期 Vue生命周期&#xff1a;就是一个Vue实例从创建 到 销毁 的整个过程 生命周期四个阶段&#xff1a;① 创建 ② 挂载 ③ 更新 ④ 销毁 1.创建阶段&#xff1a;创建响应式数据 2.挂载阶段&#xff1a;渲染模板 3.更新阶段&#xff1a;修改数据&#xff0c;更新视图 4…