leetcode常用解题方案总结

1.数组与字符串

1. 双指针法

1.思路

  • 通过两个指针在数组或字符串上按照特定规则移动,解决诸如查找、匹配、计算等问题。指针的移动方向和条件取决于具体问题,可相向、同向移动等。

2.经典案例

LeetCode 11. 盛最多水的容器

  • 在表示竖线高度的数组上,双指针分别指向数组两端,根据指针所指高度调整指针位置,计算并更新容器最大水量。

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

  • 在有序数组中,利用双指针从两端开始移动,根据两指针所指元素和与目标值的关系,找到和为目标值的两个数。

2.滑动窗口法

1.思路

  • 在字符串或数组上维护一个窗口,通过移动窗口的起始和结束位置,动态调整窗口内元素,以满足特定条件,如寻找特定子串、子数组等。窗口大小可固定或动态变化。

2.经典案例

LeetCode 3. 无重复字符的最长子串

  • 在字符串上通过滑动窗口,确保窗口内无重复字符,从而找到最长无重复子串。

LeetCode 76. 最小覆盖子串

  • 在字符串 s 上利用滑动窗口,先扩大窗口使其包含字符串 t 的所有字符,再缩小窗口找到覆盖 t 的最小子串。

3.前缀和法

1.思路

  • 对数组进行预处理,生成一个前缀和数组,其中每个元素表示原数组从起始位置到该位置的元素之和。利用前缀和数组可以高效解决子数组求和、特定和的子数组计数等问题。

2.经典案例

LeetCode 303. 区域和检索 - 数组不可变

  • 通过前缀和数组快速计算给定区间内的元素之和。

LeetCode 560. 和为 K 的子数组

  • 借助前缀和数组,统计和为 K 的子数组的个数。

2.链表

1.双指针法(链表场景)

1.思路

  • 在链表上使用两个指针,根据问题需求同步或异步移动指针,用于检测链表特性(如环)、查找特定节点等。

2.经典案例

  • 在判断链表是否有环的问题中(类似 LeetCode 141. 环形链表),快慢指针同时移动,快指针每次移动两步,若快慢指针相遇则存在环。

3.树

1.深度优先搜索(DFS) - 递归实现

1.思路

  • 沿着树的深度优先探索节点,先访问根节点,然后递归地访问左子树和右子树(对于二叉树)。可用于遍历树、计算节点值、查找特定节点等。

2.经典案例

  • 在二叉树的前序遍历(LeetCode 144. 二叉树的前序遍历)中,先访问根节点,再递归前序遍历左子树,最后递归前序遍历右子树。

2.广度优先搜索(BFS) - 队列实现

1.思路

  • 按树的层次逐层访问节点,使用队列辅助实现。先将根节点入队,每次从队列取出一个节点,访问它并将其孩子节点入队,直到队列为空。常用于按层遍历树、解决与层次相关的问题。

2.经典案例

  • 在二叉树的层序遍历(LeetCode 102. 二叉树的层序遍历)中,通过队列实现按层访问二叉树的所有节点。

4.栈

1.单调栈法

1.思路

  • 利用栈维护一个单调递增或递减的序列,通过入栈和出栈操作,解决寻找下一个更大元素、下一个更小元素等问题。

2.经典案例

LeetCode 496. 下一个更大元素 I

  • 遍历数组,利用单调栈记录每个元素的下一个更大元素。

LeetCode 84. 柱状图中最大的矩形

  • 通过单调栈维护柱子高度,计算柱状图中最大矩形面积。

5.堆

1.堆(优先队列)法

1.思路

  • 利用堆的特性维护数据的优先级,通过插入和删除操作,解决前 K 个最大或最小元素、中位数等问题。

2.经典案例

LeetCode 215. 数组中的第 K 个最大元素

  • 使用最小堆获取数组中第 K 个最大元素。

LeetCode 347. 前 K 个高频元素

  • 结合哈希表统计频率,利用优先队列(最大堆)获取前 K 个高频元素。

6.通用的算法策略

1.二分查找法

适用场景

  • 主要用于有序数组或可转化为有序结构的场景。

算法思路

  • 每次将搜索区间缩小一半,通过比较中间元素与目标值的大小关系,决定在左半部分还是右半部分继续搜索,从而快速定位目标元素或满足特定条件的位置。

经典案例

LeetCode 704. 二分查找

  • 在有序数组中查找目标值,每次比较中间元素与目标值,缩小搜索范围,直到找到目标值或确定目标值不存在。

LeetCode 33. 搜索旋转排序数组

  • 对于旋转排序数组,通过判断中间元素与两端元素的关系,确定有序部分,然后在有序部分进行二分查找。

2.动态规划法

适用场景

  • 适用于具有最优子结构和子问题重叠性质的问题,可用于数组、字符串、图等多种数据结构相关问题。

算法思路

  • 将复杂问题分解为相互关联的子问题,通过定义状态和状态转移方程,求解子问题并保存其解,避免重复计算,最终得到原问题的解。

经典案例

LeetCode 5. 最长回文子串

  • 定义二维状态 dp [i][j] 表示字符串 s 从 i 到 j 是否为回文串,通过状态转移方程和边界条件计算最长回文子串。

LeetCode 70. 爬楼梯

  • 定义状态 dp [i] 表示爬到第 i 阶楼梯的方法数,依据状态转移方程和边界条件计算爬到楼顶的方法总数。

3.回溯法

适用场景

  • 常用于解决组合、排列、路径搜索等问题,涉及对所有可能情况进行深度优先搜索。

算法思路

  • 从初始状态开始,逐步探索所有可能路径。若当前路径不符合要求,则回溯到上一个状态,尝试其他路径,直到找到所有解或满足条件的解。

经典案例

LeetCode 46. 全排列

  • 从空排列开始,通过回溯依次添加未使用数字,生成所有全排列。

LeetCode 93. 复原 IP 地址

  • 通过在字符串中回溯插入点,将字符串分成 4 段,判断每段合法性,得到所有有效 IP 地址。

4.贪心算法

适用场景

  • 适用于具有贪心选择性质的问题,即局部最优选择能导致全局最优解,常见于资源分配、调度等问题。

算法思路

  • 在每一步决策中,选择当前状态下的最优解,不考虑整体最优解,期望通过一系列局部最优选择达到全局最优。

经典案例

LeetCode 455. 分发饼干

  • 对孩子胃口值和饼干尺寸排序后,从胃口最小孩子和尺寸最小饼干开始匹配,每次选择能满足当前孩子的最小饼干。

LeetCode 122. 买卖股票的最佳时机 II

  • 每天判断当前价格与前一天价格,若当前价格高则进行买卖操作累加利润。

5.分治法

适用场景

  • 适用于可以分解为若干个规模较小、相互独立且与原问题形式相同的子问题的场景,如树的相关问题、数组划分问题等。

算法思路

  • 将问题分解为子问题,递归地解决子问题,然后合并子问题的解得到原问题的解。

经典案例

LeetCode 241. 为运算表达式设计优先级

  • 按运算符分割表达式为左右两部分,递归计算左右部分结果,再根据运算符组合结果。

LeetCode 53. 最大子数组和

  • 将数组分成左右两部分,分别计算左右部分最大子数组和以及跨越中点的最大子数组和,取三者最大值。
相关推荐
惜.己3 小时前
针对nvm不能导致npm和node生效的解决办法
前端·npm·node.js
ulias2123 小时前
各种背包问题简述
数据结构·c++·算法·动态规划
m0_570466413 小时前
代码随想录算法训练营第二十八天 | 买卖股票的最佳实际、跳跃游戏、K次取反后最大化的数组和
java·开发语言·算法
吃着火锅x唱着歌3 小时前
LeetCode 1537.最大得分
算法·leetcode·职场和发展
数模加油站3 小时前
25高教社杯数模国赛【C题超高质量思路+可运行代码】第十弹
算法·数学建模·数模国赛·高教社杯全国大学生数学建模竞赛
F2E_Zhangmo4 小时前
基于cornerstone3D的dicom影像浏览器 第二章 加载本地文件夹中的dicom文件并归档
前端·javascript·css
ulias2124 小时前
动态规划入门:从记忆化搜索到动态规划
算法·动态规划
山河君4 小时前
webrtc之语音活动上——VAD能量检测原理以及源码详解
算法·音视频·webrtc·信号处理
用户21411832636024 小时前
Nano Banana免费方案来了!Docker 一键部署 + 魔搭即开即用,小白也能玩转 AI 图像编辑
前端