常见数据结构及算法

必须掌握的数据结构及算法

掌握数据结构是应用算法的基础,以下是一些核心结构及其典型应用场景:

  • 栈与队列 用于深度优先搜索、括号匹配;队列用于广度优先搜索、滑动窗口。

  • 哈希表 :提供O(1)时间的快速查找,常用于缓存(LRU)统计频率、快速判断元素是否存在(如两数之和)。

  • 堆(优先队列) :能快速获取最大或最小元素,常用于解决Top K问题 、求中位数等。

  • 二叉树 的遍历(前、中、后序)是基础;二叉搜索树 支持高效查找;字典树专门处理字符串前缀问题。

  • 并查集 :高效处理分组连通性问题(如朋友圈、岛屿数量变种)。

  • 前缀和与差分

    • 前缀和:用于快速计算数组某个区间的和。

    • 差分:是前缀和的逆运算,用于高效地对数组的某个区间进行批量增减操作

下面这个表格整理了最常见的算法思想、核心概念:

|---------------------|-------------------------------------------------|
| 算法分类/思想 | 核心思想/概念 |
| 滑动窗口 | 维护一个可变或固定大小的窗口,在数组/链表/字符串上滑动,高效解决子数组/子串问题。 |
| 双指针 | 使用两个指针协同工作,包括左右指针(用于有序数组的两数之和等)和快慢指针(用于判断链表环等)。 |
| 二分查找 | 在有序搜索空间中,通过比较中间元素快速缩小范围,时间复杂度通常为O(log n)。 |
| 深度/广度优先搜索 (DFS/BFS) | DFS:递归或栈,用于遍历或搜索树/图。 BFS:队列,用于层序遍历或最短路径。 |
| 回溯法 | 一种通过试错寻找所有解的算法,在遇到不可行解时"回溯"至上一步。 |
| 动态规划 (DP) | 将复杂问题分解为重叠子问题,并存储子问题的解以避免重复计算。 |
| 贪心算法 | 每一步都采取当前状态下局部最优的选择,以期望得到全局最优解。 |
| 分治法 | 将问题分解成多个独立的子问题,递归求解后再合并结果。 |

下面以数组 3,1,4,1,5,9 为例,展示滑动窗口、双指针、二分查找、DFS/BFS、回溯法、动态规划、贪心算法和分治法的核心思维差异:

各算法详细解析与经典题目

🔍 1. 滑动窗口

  • 核心思想 :维护一个窗口(通常由两个指针leftright界定),在数组或字符串上滑动。通过移动右指针扩大窗口,满足条件后移动左指针收缩窗口,从而在**O(n)**时间内找到满足条件的子区间。

  • 关键点 :用于解决连续子数组/子串问题。窗口内的状态(如字符频率、和、最大值)需要高效维护(常用哈希表或单调队列)。

  • 经典题目

    • 3. 无重复字符的最长子串:用哈希集合记录窗口内字符,确保无重复。

    • 239. 滑动窗口最大值 :使用单调递减队列在O(1)时间内获取窗口最大值。

↔️ 2. 双指针

  • 核心思想:使用两个指针协同遍历,减少时间复杂度。主要有两种形式:

    1. 左右指针 :在有序数组两端向中间移动,用于两数之和、反转数组等。

    2. 快慢指针 :在链表或数组上,以不同速度移动,用于判断循环、找中点、找交点等。

  • 关键点:通常能将O(n²)的暴力解法优化到O(n)。

  • 经典题目

    • 167. 两数之和 II(有序数组):左右指针经典应用。

    • 142. 环形链表 II:快慢指针找到环的入口,是数学和编程的巧妙结合。

🔎 3. 二分查找

  • 核心思想 :在有序的搜索空间中,每次通过比较中间元素,将待搜索区间缩小一半。

  • 关键点 :难点在于边界条件while<还是<=mid加一还是减一)。有寻找精确值、寻找左边界、寻找右边界三种基本变体。

  • 经典题目

    • 34. 在排序数组中查找元素的第一个和最后一个位置:二分查找左右边界的标准模板题。

    • 33. 搜索旋转排序数组:二分查找的进阶,需要在局部有序中判断搜索方向。

🌳 4. 深度/广度优先搜索

  • 核心思想

    • DFS :深度优先,一条路走到黑,用递归 实现。常用于遍历所有路径、排列组合、连通性问题。

    • BFS :广度优先,一层层向外扩展,用队列 实现。常用于最短路径、层序遍历

  • 关键点 :必须注意避免重复访问 (使用visited集合或标记已访问元素)。

  • 经典题目

    • 200. 岛屿数量:网格DFS/BFS的典范,用"淹没"思想标记访问过的陆地。

    • 102. 二叉树的层序遍历:BFS的经典应用。

🧩 5. 回溯法

  • 核心思想 :一种系统性试错 的算法。它沿决策树前进,当探索到某步发现当前选择不满足条件时,就撤销(回溯) 上一步或几步的选择,尝试其他可能性。

  • 关键点 :其核心框架是一个递归函数,包含:选择 -> 递归 -> 撤销选择 。解决全排列、子集、组合、N皇后等需要枚举所有可能解的问题。

  • 经典题目

    • 46. 全排列:回溯法最直观的演示,理解"路径"和"选择列表"。

    • 78. 子集:求所有子集是另一种经典的回溯场景。

🧮 6. 动态规划

  • 核心思想 :将复杂问题分解为重叠的子问题 ,并通过保存子问题的解(通常用数组dp)来避免重复计算,从而高效求解原问题。

  • 关键点 :写出正确的 "状态转移方程" 是核心。思考步骤:1) 定义dp[i]的意义;2) 找出dp[i]如何由dp[0...i-1]推导(状态转移);3) 确定初始值(dp[0]等)。

  • 经典题目(按难度进阶):

    • 70. 爬楼梯 :入门必做,理解dp[i] = dp[i-1] + dp[i-2]

    • 53. 最大子数组和 :理解"dp[i]是以nums[i]结尾的最大和"这一关键定义。

    • 300. 最长递增子序列 :经典的一维DP,dp[i]与之前所有j < i的状态有关。

    • 1143. 最长公共子序列:经典的二维DP,理解文本比较的模型。

🍬 7. 贪心算法

  • 核心思想 :每一步都做出当前看来最优的选择,并希望这样的局部最优能导致全局最优。

  • 关键点:难点在于证明贪心策略的正确性。它不像DP考虑所有子问题,因此效率更高,但适用场景更窄。

  • 经典题目

    • 455. 分发饼干:经典入门题,用小饼干满足小胃口。

    • 122. 买卖股票的最佳时机II:只要今天比昨天贵,就假设昨天买入今天卖出(贪心思想)。

➗ 8. 分治法

  • 核心思想 :将一个大问题分解成若干个独立的、形式相同的子问题 ,递归求解子问题,最后合并子问题的结果得到原问题的解。

  • 关键点 :与DP的关键区别在于,分治法的子问题通常不重叠。归并排序和快速排序是分治法的典型代表。

  • 经典题目

    • 215. 数组中的第K个最大元素:通常使用基于快速排序选择算法的分治思想。

    • 23. 合并K个升序链表:可以两两合并(分治),优于顺序合并。

算法选择指南

  1. 识别问题特征
问题特征 优先考虑算法 原因
看到:连续子数组/子串 滑动窗口 天然适合处理连续区间问题
看到:有序数组查找 二分查找 O(log n) 高效查找
看到:所有可能解/排列/组合 回溯法 系统枚举所有可能性
看到:最优解 + 重叠子问题 动态规划 避免重复计算,得到最优解
局部最优 → 全局最优 贪心算法 高效,但需要证明正确性
可独立分解的子问题 分治法 递归分解,适合并行处理
图/树遍历,最短路径 BFS/DFS 适合层级或深
  1. 混合使用策略

    • DFS + 记忆化 = 记忆化搜索(一种DP实现方式)

    • 二分查找 + 贪心 = 解决"最小化最大值"问题

    • BFS + 优先队列 = Dijkstra算法

相关推荐
kebidaixu2 小时前
两轮BMS 防打火策略详解
算法
wabs6663 小时前
关于动态规划【力扣1035.不相交的线和53.最大子数组和的思考】
算法·leetcode·动态规划
退休倒计时3 小时前
【每日一题】LeetCode 199. 二叉树的右视图 TypeScript
算法·leetcode·typescript
可编程芯片开发3 小时前
通过MATLAB实现PID控制器,积分分离控制器以及滑模控制器
算法
小O的算法实验室3 小时前
2026年ESWA,基于全局进化动态规划与局部粒子群优化GPU 支持去中心化多机器人路径规划
动态规划
kebidaixu4 小时前
两轮BMS 短路保护策略详解
算法
zwenqiyu4 小时前
非线性字符串数据结构串讲
数据结构·c++·学习·算法
z小猫不吃鱼4 小时前
03 Optimal Brain Surgeon 详解:Hessian 剪枝为什么有效?
算法·机器学习·剪枝
硕风和炜4 小时前
【LeetCode: 1301. 最大得分的路径数目 + DP】
java·算法·leetcode·动态规划·dp·记忆化搜索
用户99045017780094 小时前
做了一个AI诊断,参考倪海厦中医理论,科学养生
算法