这里把 LeetCode 面试里经常碰到的一批题目整理了一下,覆盖排序、查找、链表、动态规划这些最容易反复出现的模块。不是要把每题都讲到源码级别,而是先把思路捋顺:什么时候该用分治,什么时候该上双指针,什么时候靠回溯硬搜,心里有谱,做题时才不会被题型带着跑。
一、核心排序算法
1. 快速排序
快速排序在面试里很常见,原因很简单:它把'怎么排'拆成了'怎么分'。先选一个基准值,把数组分成左右两边,再递归处理,最后自然有序。
- 步骤解析:
- 选择基准值:从数组中选一个元素作为 pivot,通常选首元素或中间元素。
- 分区操作:重排数组,让小于基准的在左边,大于的在右边。
- 递归排序:对左右子数组递归应用快速排序。
- 合并结果:原地排序,递归结束即完全有序,无需额外合并。
- 核心要点:基准值的选择直接影响性能,理想情况应选中位数。
2. 堆排序
堆排序靠的是堆这个结构本身的性质:每次都把最大值放到堆顶,再不断把堆顶换到数组末尾,范围缩小后继续调整。
- 步骤解析:
- 构建最大堆:从最后一个非叶子节点开始自底向上下沉,确保父节点大于子节点。
- 交换堆顶元素:将最大值(堆顶)与当前堆末尾交换。
- 重新调整堆:缩小堆范围,对新堆顶执行下沉操作恢复性质。
- 重复过程:直到堆大小缩减为 1。
- 核心要点:非稳定排序,时间复杂度 O(n log n),适合大数据集。
3. 归并排序
归并排序是典型的分治。它不急着在原数组里'挪位置',而是先拆到最小,再把有序段合回来,所以稳定性很好,代价是要额外空间。
- 步骤解析:
- 分解数组:递归二分,直到子数组仅含一个元素。
- 合并排序:合并两个已排序的子数组。
- 递归实现:分解与合并通过递归完成。
- 辅助空间:合并需临时数组存储中间结果。
- 核心要点:稳定排序,O(n log n),适合数据量大且要求稳定性的场景。
二、经典查找算法
4. 二分查找
二分查找的前提只有一个:数组有序。满足这个条件后,它就是最省比较次数的查找方式之一。
- 步骤解析:
- 初始化边界:
low = 0,high = 数组长度 - 1。 - 计算中间索引:
mid = low + (high - low) / 2。 - 比较中间元素:对比
arr[mid]与target。 - 调整搜索范围:根据大小关系决定向左或向右区间继续查找。
- 重复查找:直到找到目标或区间为空。
- 初始化边界:
- 核心要点:对数级比较次数,时间复杂度 O(log n)。
5. 寻找无序数组的中位数
无序数组里找中位数,最朴素的办法当然是先排再取;但如果数据量大,或者只想找第 n/2 个位置,快速选择和堆通常更合适。

