算法是编程的灵魂,也是面试中的重点考察内容。本文精选了几道经典算法题,涵盖字符串处理、链表操作、树遍历等常见场景,通过详细解析帮助你理解算法设计思路与实现细节,提升解题能力。

一、无重复字符的最长子串

题目描述

给定一个字符串 s,请你找出其中不含有重复字符的最长子串的长度。

示例

  • 输入:s = "abcabcbb" → 输出:3(最长子串是 "abc"
  • 输入:s = "bbbbb" → 输出:1(最长子串是 "b"
  • 输入:s = "pwwkew" → 输出:3(最长子串是 "wke"

解题思路:滑动窗口 + 哈希表

滑动窗口是处理子串问题的高效方法,核心是维护一个动态窗口 [left, right],确保窗口内的字符无重复。配合哈希表记录字符最后出现的位置,可快速调整窗口边界。

代码实现

def length_of_longest_substring(s):char_map = {}  # 记录字符最后出现的位置left = 0       # 滑动窗口左边界max_len = 0    # 最大长度for right in range(len(s)):current_char = s[right]# 若当前字符已存在且在窗口内,移动左边界if current_char in char_map and char_map[current_char] >= left:left = char_map[current_char] + 1# 更新字符的最新位置char_map[current_char] = right# 计算当前窗口长度并更新最大值current_len = right - left + 1max_len = max(max_len, current_len)return max_len

详细解析

  1. 核心变量

    • left 和 right 分别为窗口的左右边界,初始时 left=0
    • char_map 存储每个字符最后一次出现的索引,用于快速判断重复。
    • max_len 记录最长无重复子串的长度。
  2. 窗口调整逻辑

    • 遍历字符串时,right 不断右移,扩大窗口范围。
    • 若当前字符 current_char 已在 char_map 中,且上次出现的位置在窗口内(char_map[current_char] >= left),说明出现重复,需将左边界 left 移到上次出现位置的下一位(char_map[current_char] + 1),确保窗口内无重复。
    • 每次移动后,计算当前窗口长度(right - left + 1),并更新 max_len
  3. 复杂度分析

    • 时间复杂度:O (n),每个字符仅被遍历一次。
    • 空间复杂度:O (min (n, m)),m 为字符集大小(如 ASCII 字符集为 256)。

二、合并两个有序链表

题目描述

将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例
输入:l1 = [1,2,4]l2 = [1,3,4]
输出:[1,1,2,3,4,4]

解题思路:递归法

递归是处理链表问题的常用思路,通过比较两个链表的当前节点值,递归合并剩余节点,代码简洁直观。

代码实现

# 定义链表节点
class ListNode:def __init__(self, val=0, next=None):self.val = valself.next = nextdef merge_two_lists(l1, l2):# 若其中一个链表为空,直接返回另一个if not l1:return l2if not l2:return l1# 递归合并if l1.val <= l2.val:l1.next = merge_two_lists(l1.next, l2)return l1else:l2.next = merge_two_lists(l1, l2.next)return l2

详细解析

  1. 递归终止条件

    • 若 l1 为空,返回 l2(空链表与非空链表合并结果为非空链表)。
    • 若 l2 为空,返回 l1,逻辑同上。
  2. 递归逻辑

    • 比较 l1.val 和 l2.val,选择值较小的节点作为当前合并链表的节点。
    • 递归合并该节点的 next 指针与另一个链表,形成新的链表。
    • 返回当前选择的节点,作为合并后链表的一部分。
  3. 示例验证
    以 l1 = [1,2,4] 和 l2 = [1,3,4] 为例:

    • 比较 l1.val=1 和 l2.val=1,选择 l1,递归合并 l1.next=[2,4] 与 l2=[1,3,4]
    • 后续步骤类似,最终合并结果为 [1,1,2,3,4,4]
  4. 复杂度分析

    • 时间复杂度:O (m + n),m 和 n 分别为两链表长度,需遍历所有节点。
    • 空间复杂度:O (m + n),递归栈深度最坏情况下为两链表长度之和。

三、有效的括号

题目描述

给定一个只包括 '('')''{''}''['']' 的字符串 s,判断字符串是否有效。有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。

示例

  • 输入:s = "()" → 输出:True
  • 输入:s = "()[]{}" → 输出:True
  • 输入:s = "(]" → 输出:False

解题思路:栈结构

栈的 “后进先出” 特性非常适合处理括号匹配问题:左括号入栈,右括号则弹出栈顶元素检查是否匹配。

代码实现

def is_valid(s):stack = []  # 存储左括号的栈mapping = {')': '(', ']': '[', '}': '{'}  # 右括号到左括号的映射for char in s:# 若为右括号,检查栈顶元素是否匹配if char in mapping:# 栈为空或栈顶元素不匹配,返回Falseif not stack or stack.pop() != mapping[char]:return False# 若为左括号,直接入栈else:stack.append(char)# 遍历结束后,栈应为空return len(stack) == 0

详细解析

  1. 栈与哈希表的配合

    • 栈 stack 用于存储左括号,遇到左括号直接入栈。
    • 哈希表 mapping 存储右括号到左括号的映射,方便快速查找匹配的左括号(如 ')' 对应 '(')。
  2. 匹配逻辑

    • 遍历字符串中的每个字符:
      • 若为右括号:
        • 若栈为空,说明没有左括号与之匹配,返回 False
        • 弹出栈顶元素,若与当前右括号不匹配(如 ')' 对应栈顶不是 '('),返回 False
      • 若为左括号,直接入栈。
    • 遍历结束后,若栈不为空,说明存在未匹配的左括号,返回 False;否则返回 True
  3. 示例验证
    输入 s = "([)]"

    • 遍历到 '(',入栈 → 栈:['(']
    • 遍历到 '[',入栈 → 栈:['(', '[']
    • 遍历到 ')',栈顶为 '[',不匹配 → 返回 False
  4. 复杂度分析

    • 时间复杂度:O (n),遍历字符串一次。
    • 空间复杂度:O (n),最坏情况下栈存储所有左括号。

四、二叉树的中序遍历

题目描述

给定一个二叉树的根节点 root,返回它的中序遍历结果。(中序遍历顺序:左子树 → 根节点 → 右子树)

示例
输入:root = [1,null,2,3](二叉树结构:根节点 1,右子节点 2,2 的左子节点 3)
输出:[1,3,2]

解题思路:递归法

递归是实现树遍历的直观方法,中序遍历的递归逻辑为:先遍历左子树,再访问根节点,最后遍历右子树。

代码实现

# 定义二叉树节点
class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef inorder_traversal(root):result = []def inorder(node):if node is None:return# 递归遍历左子树inorder(node.left)# 访问根节点result.append(node.val)# 递归遍历右子树inorder(node.right)inorder(root)return result

详细解析

  1. 递归函数设计

    • 辅助函数 inorder(node) 用于实现中序遍历,参数为当前节点 node
    • 终止条件:若 node 为空,直接返回(空树无需遍历)。
  2. 遍历顺序

    • 递归遍历左子树:inorder(node.left),确保左子树所有节点先于根节点被访问。
    • 访问根节点:将当前节点值加入结果列表 result
    • 递归遍历右子树:inorder(node.right),确保右子树所有节点后于根节点被访问。
  3. 示例验证
    对于 root = [1,null,2,3]

    • 调用 inorder(1),先遍历左子树(为空),访问 1 → result = [1]
    • 递归遍历右子树 2,先遍历其左子树 3:访问 3 → result = [1,3]
    • 访问 2 → result = [1,3,2],最终返回 [1,3,2]
  4. 复杂度分析

    • 时间复杂度:O (n),遍历所有节点一次。
    • 空间复杂度:O (h),h 为树的高度,递归栈深度取决于树高,最坏情况(链状树)为 O (n)。

总结

本文通过四道经典算法题,展示了滑动窗口、递归、栈等数据结构与算法的实际应用。解题的核心在于:

  1. 问题拆解:将复杂问题转化为可通过特定数据结构或算法解决的子问题(如用栈处理括号匹配)。
  2. 逻辑设计:明确变量含义、边界条件和处理流程(如滑动窗口中左右边界的动态调整)。
  3. 复杂度优化:在实现功能的基础上,考虑时间和空间效率(如用哈希表降低查找时间)

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Unity游戏】——1.俄罗斯方块

搭建场景 使用任意方块、纯色瓦片或者其他图形作为背景&#xff0c;设置其大小与目标大小一致或者更大&#xff0c;设置左下角为场景顶点&#xff0c;并放置在&#xff08;0&#xff0c;0&#xff09;处。调整摄像机至合适位置。 制作游戏预制体 每个方块预制体包含有4个小方…

【C++进阶】---- 二叉搜索树

1.二叉搜索树的概念 ⼆叉搜索树⼜称⼆叉排序树&#xff0c;它或者是⼀棵空树&#xff0c;或者是具有以下性质的⼆叉树: • 若它的左⼦树不为空&#xff0c;则左⼦树上所有结点的值都⼩于等于根结点的值 • 若它的右⼦树不为空&#xff0c;则右⼦树上所有结点的值都⼤于等于根结…

基于 OpenCV 与 sklearn 的数字识别:KNN 算法实践

在计算机视觉领域&#xff0c;数字识别是一个经典问题&#xff0c;广泛应用于邮政编码识别、车牌识别等场景。本文将介绍如何使用 OpenCV 进行图像处理&#xff0c;并结合 KNN&#xff08;K 近邻&#xff09;算法实现数字识别&#xff0c;同时对比 OpenCV 内置 KNN 与 scikit-l…

利用径向条形图探索华盛顿的徒步旅行

利用径向条形图探索华盛顿的徒步旅行 import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np import pandas as pdfrom matplotlib.cm import ScalarMappable from matplotlib.lines import Line2D from mpl_toolkits.axes_grid1.inset_locator impor…

火狐浏览器中国特供版关闭,如何下载 Firefox 国际版?如何备份数据?

火狐浏览器中国特供版关闭&#xff0c;如何下载 Firefox 国际版&#xff1f;如何备份数据&#xff1f;各位火狐老用户注意了&#xff01;7 月 27 日北京谋智火狐正式发布公告&#xff1a;2025 年 9 月 29 日 24:00 起&#xff0c;中国特供版账户服务将彻底关闭&#xff0c;所有…

C语言操作符详解:从基础到进阶

在C语言中&#xff0c;操作符是构建表达式的基础&#xff0c;掌握各类操作符的用法、优先级及特性&#xff0c;对写出高效且正确的代码至关重要。本文将系统梳理C语言操作符的核心知识点&#xff0c;包含实例代码与详细解析&#xff0c;助你彻底搞懂操作符。 1. 操作符的分类 C…

鸿蒙平台运行Lua脚本

1. 目标 使用 rust 在移动端实现 Lua 脚本的运行。 2. 核心步骤 [Rust Host App]│├── [mLua VM] (通过 mlua 或 rlua 库嵌入)│ ├── 独立Lua状态&#xff08;隔离执行&#xff09;│ ├── 受限标准库&#xff08;禁用危险函数&#xff09;│ └── 内存/CPU限…

【Ubuntu】发展历程

Ubuntu 是一个基于 Debian 的 Linux 发行版&#xff0c;由 Canonical 公司开发和维护。它以其易用性、稳定性和强大的社区支持而著称。以下是 Ubuntu 从发布以来的主要版本和发展历程&#xff1a;1. Ubuntu 4.10 "Warty Warthog" (2004)发布日期&#xff1a;2004年10…

k8s下springboot-admin 监控服务部署,客户端接入

踩坑及解决以下问题 1、客户端监控信息不显示,需要暴露监控检查接口路径 2、服务端不显示客户端日志,需要启用日志,并指定日志路径 3、解决在k8s下,客户端多实例注册id相同,如2个实例只显示一个 整体架构 springboot-admin 由服务端和客户端组成 服务端负责 1、提供 We…

git删除远程分支和本地分支

1. git删除远程分支 git push origin --delete [branch_name]2. 删除本地分支 2.1 git branch -d 会在删除前检查merge状态&#xff08;其与上游分支或者与head&#xff09;。 git branch -d [branch_name] 2.2 git branch -D 直接删除 git branch -D 是 git branch --delete…

Go 的时间包:理解单调时间与挂钟时间

Go 的时间包&#xff1a;理解单调时间与挂钟时间 &#x1f4c5; 引言 Go 语言自版本 1.9 起在 time.Time 中同时支持 “挂钟时间&#xff08;wall‑clock&#xff09;” 和 “单调时间&#xff08;monotonic clock&#xff09;”&#xff0c;用于分别满足时间戳与时间间隔测量…

Android启动时间优化大全

1 修改Android mksh默认的列长度 不修改这个参数&#xff0c;adb shell后&#xff0c;输入超过80个字符&#xff0c;就不能看到完整的命令行。external/mksh/src/sh.h EXTERN mksh_ari_t x_cols E_INIT(80); EXTERN mksh_ari_t x_lins E_INIT(24);2 Kernel优化 2.1 内核驱动模块…

matplotlib.pyplot: 底层原理简析与进阶技巧

文章目录 1 底层实现原理 1.1 核心架构 1.1 渲染流程 2 基础用法 2.1 基本绘图 2.2 多子图系统 2.3 高阶用法 2.3.1 自定义Artist对象 2.3.2 高级动画技术 2.3.3 事件处理系统 2.3.4 混合渲染技术 3 性能优化技巧 4 扩展模块 5 总结 5.1 底层原理关键点 5.2 进阶技巧 1 底层实现…

深入理解现代前端开发中的 <script type=“module“> 与构建工具实践

引言&#xff1a;模块化开发的演进在早期的前端开发中&#xff0c;JavaScript 缺乏原生的模块化支持&#xff0c;开发者不得不依赖 IIFE&#xff08;立即调用函数表达式&#xff09;或第三方库&#xff08;如 RequireJS&#xff09;来实现代码组织。随着 ES6&#xff08;ES2015…

yolo--qt可视化开发

qt5可能不支持我们的cuda版本&#xff0c;改用qt6 YOLO11QT6OpencvC训练加载模型全过程讲解_yolov11 模型转换成opencv c模型-CSDN博客 下面是qt5版本的案例&#xff0c;和yolo及cuda有冲突 安装qt 切换到虚拟环境&#xff0c;例如pyqt&#xff0c;conda activate pyqt pip …

SQL性能优化

show [session|global] status : 查看服务器状态 show global status like Com_ : 查看各种语句的执行次数 开启慢查询: 在 MySQL 配置文件&#xff08;/etc/my.cnf&#xff09;配置: #开启MySQL慢日志查询开关 slow_query_log1 #设置慢日志的时间为2秒&#xff0c;SQL语句执…

ctfshow pwn40

目录 1. 分析程序 2. 漏洞编写 3. 漏洞验证 1. 分析程序 首先检查程序相关保护&#xff0c;发现程序为32位且只开启了一个NX保护 checksec pwn 使用IDA进行逆向分析代码&#xff0c;查看漏洞触发点&#xff1a; 在main函数中&#xff0c;有一个ctfshow函数&#xff0c;这里…

SQL173 店铺901国庆期间的7日动销率和滞销率

SQL173 店铺901国庆期间的7日动销率和滞销率 SQL题解&#xff1a;店铺动销率与滞销率计算 关键&#xff1a;只要当天任一店铺有任何商品的销量就输出该天的结果&#xff0c;即使店铺901当天的动销率为0。 潜台词&#xff1a;​输出逻辑与店铺901的销售情况无关&#xff0c;只取…

PytorchLightning最佳实践基础篇

PyTorch Lightning&#xff08;简称 PL&#xff09;是一个建立在 PyTorch 之上的高层框架&#xff0c;核心目标是剥离工程代码与研究逻辑&#xff0c;让研究者专注于模型设计和实验思路&#xff0c;而非训练循环、分布式配置、日志管理等重复性工程工作。本文从基础到进阶&…

Apache Flink 实时流处理性能优化实践指南

Apache Flink 实时流处理性能优化实践指南 随着大数据和实时计算需求不断增长&#xff0c;Apache Flink 已经成为主流的流处理引擎。然而&#xff0c;在生产环境中&#xff0c;高并发、大吞吐量和低延迟的业务场景对 Flink 作业的性能提出了更高要求。本文将从原理层面深入解析…