数组分区和荷兰国旗只差一个条件:稳定性

一、稳定性是这道题的关键约束

LeetCode 2161 要求把数组按 pivot 分成三部分:小于、等于、大于,且保持相对顺序不变

这个约束直接排除了经典的荷兰国旗双指针交换解法。交换会打乱元素的原始顺序,而这道题恰好需要"稳定分区"。


二、两种解法

解法一:三次遍历

javascript 复制代码
var pivotArray = function(nums, pivot) {
    const n = nums.length, ans = new Array(n);
    let idx = 0;
    for (let i = 0; i < n; i++) if (nums[i] < pivot) ans[idx++] = nums[i];
    for (let i = 0; i < n; i++) if (nums[i] === pivot) ans[idx++] = nums[i];
    for (let i = 0; i < n; i++) if (nums[i] > pivot) ans[idx++] = nums[i];
    return ans;
};

解法二:一次遍历 + 三数组

javascript 复制代码
var pivotArray = function(nums, pivot) {
    const less = [], equal = [], greater = [];
    for (const num of nums) {
        if (num < pivot) less.push(num);
        else if (num === pivot) equal.push(num);
        else greater.push(num);
    }
    return [...less, ...equal, ...greater];
};

两种解法都是 O(n) 时间 + O(n) 空间。第一种内存访问更连续,第二种写法更简洁。


三、荷兰国旗的交换为什么不适用

荷兰国旗问题用三指针一次遍历完成分区:

javascript 复制代码
let i = 0, left = 0, right = n - 1;
while (i <= right) {
    if (nums[i] < pivot) [nums[i++], nums[left++]] = [nums[left], nums[i]];
    else if (nums[i] > pivot) [nums[i], nums[right--]] = [nums[right], nums[i]];
    else i++;
}

这段代码正确地将数组分成了三部分,但不保证稳定性------因为交换操作无法维持元素间的相对顺序。当一个元素被 swap 到后面时,它和后续元素的关系就变了。


四、总结

  1. 稳定分区要求排除了双指针交换,只能用顺序收集
  2. 三次遍历和一次遍历+三数组本质等价
  3. 这道题的核心不是"如何分区",而是"在稳定的前提下如何分区"
  4. 理解稳定性的含义,比记住解法更重要
相关推荐
miller-tsunami2 天前
排序的相关知识点
数据结构·排序算法
wuyk5553 天前
21.计数排序:不用比较的“空间换时间”排序算法
python·算法·排序算法
Zane19943 天前
比较排序跑不出O(nlogn)是数学上证明过的,计数、桶、基数排序凭什么能绕开这堵墙
算法·排序算法
虚无的纽扣3 天前
【力扣刷题】第三天:有效三角形的个数、快乐数
算法·排序算法
无忧.芙桃3 天前
数据结构之排序算法(中):冒泡排序与快速排序,从相邻交换到工程级优化
c语言·c++·排序算法
Zane19945 天前
归并排序和堆排序都能保证O(nlogn),为什么谁也没法把稳定和原地两个优点占全
算法·排序算法
虚无的纽扣6 天前
【力扣刷题】第二天:无重复字符的最长字串、移动零问题
算法·leetcode·排序算法
多弗朗皮卡丘6 天前
数据结构9:排序算法
c语言·数据结构·排序算法
无忧.芙桃6 天前
数据结构之排序算法(上):从评价指标到插入、希尔、选择与堆排序
c语言·c++·排序算法
LuminousCPP6 天前
数据结构-排序(五):计数排序与排序专题阶段总结|从外部归并到线性排序,再看算法边界与选型
c语言·数据结构·笔记·算法·排序算法