1. 快速排序算法基础与三路划分原理
快速排序作为最经典的排序算法之一,其核心思想是分治法。传统快排通过选取基准值将数组分为两部分,而现代优化版本更倾向于使用三路划分(Three-way Partition)来解决重复元素的问题。让我们先理解这个核心机制。
三路划分将数组分为三个区域:
- 小于基准值的元素(左侧)
- 等于基准值的元素(中部)
- 大于基准值的元素(右侧)
这种划分方式需要维护三个指针:
- left:指向小于区的末尾
- right:指向大于区的起始
- i:当前遍历指针
关键技巧:当遇到与基准值相等的元素时,只需移动i指针;遇到较小元素时与left+1位置交换;遇到较大元素时与right-1位置交换。这种策略能高效处理大量重复元素的情况。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 颜色分类问题实战解析
2.1 问题建模与算法选择
LeetCode 75题要求将仅包含0、1、2的数组原地排序。这正是三路划分的典型应用场景:
cpp复制void sortColors(vector<int>& nums) {
int n = nums.size();
int left = -1, right = n, i = 0; // 初始化三个指针
while (i < right) { // 终止条件
if (nums[i] == 0) {
swap(nums[++left], nums[i++]); // 扩展小于区
}
else if (nums[i] == 1) {
i++; // 中间区自动扩展
}
else {
swap(nums[--right], nums[i]); // 扩展大于区
}
}
}
2.2 边界条件与指针移动
需要特别注意指针移动的细节:
- left从-1开始,保证第一个0能正确交换到首位
- right从n开始,使得第一个2能交换到末尾
- 交换0时i可以立即递增(因为交换来的必然是1)
- 交换2时i不能移动(因为交换来的可能是0或1)
