2161. 根据给定数字划分数组
2161. 根据给定数字划分数组
题目
You are given a 0-indexed integer array nums and an integer pivot. Rearrange nums such that the following conditions are satisfied:
- Every element less than
pivotappears before every element greater thanpivot. - Every element equal to
pivotappears in between the elements less than and greater thanpivot. - The relative order of the elements less than
pivotand the elements greater thanpivotis maintained.- More formally, consider every
pi,pjwherepiis the new position of theithelement andpjis the new position of thejthelement. For elements less thanpivot, ifi < jandnums[i] < pivotandnums[j] < pivot, thenpi < pj. Similarly for elements greater thanpivot, ifi < jandnums[i] > pivotandnums[j] > pivot, thenpi < pj.
- More formally, consider every
Return nums after the rearrangement.
Example 1:
Input: nums = [9,12,5,10,14,3,10], pivot = 10
Output: [9,5,3,10,10,12,14]
Explanation:
The elements 9, 5, and 3 are less than the pivot so they are on the left side of the array.
The elements 12 and 14 are greater than the pivot so they are on the right side of the array.
The relative ordering of the elements less than and greater than pivot is also maintained. [9, 5, 3] and [12, 14] are the respective orderings.
Example 2:
Input: nums = [-3,4,3,2], pivot = 2
Output: [-3,2,4,3]
Explanation:
The element -3 is less than the pivot so it is on the left side of the array.
The elements 4 and 3 are greater than the pivot so they are on the right side of the array.
The relative ordering of the elements less than and greater than pivot is also maintained. [-3] and [4, 3] are the respective orderings.
Constraints:
1 <= nums.length <= 10^5-10^6 <= nums[i] <= 10^6pivotequals to an element ofnums.
题目大意
给你一个下标从 0 开始的整数数组 nums 和一个整数 pivot 。请你将 nums 重新排列,使得以下条件均成立:
- 所有小于
pivot的元素都出现在所有大于pivot的元素 之前 。 - 所有等于
pivot的元素都出现在小于和大于pivot的元素 中间 。 - 小于
pivot的元素之间和大于pivot的元素之间的 相对顺序 不发生改变。- 更正式的,考虑每一对
pi,pj,pi是初始时位置i元素的新位置,pj是初始时位置j元素的新位置。对于小于pivot的元素,如果i < j且nums[i] < pivot和nums[j] < pivot都成立,那么pi < pj也成立。类似的,对于大于pivot的元素,如果i < j且nums[i] > pivot和nums[j] > pivot都成立,那么pi < pj。
- 更正式的,考虑每一对
请你返回重新排列 nums 数组后的结果数组。
示例 1:
输入: nums = [9,12,5,10,14,3,10], pivot = 10
输出:[9,5,3,10,10,12,14]
解释:
元素 9 ,5 和 3 小于 pivot ,所以它们在数组的最左边。
元素 12 和 14 大于 pivot ,所以它们在数组的最右边。
小于 pivot 的元素的相对位置和大于 pivot 的元素的相对位置分别为 [9, 5, 3] 和 [12, 14] ,它们在结果数组中的相对顺序需要保留。
示例 2:
输入: nums = [-3,4,3,2], pivot = 2
输出:[-3,2,4,3]
解释:
元素 -3 小于 pivot ,所以在数组的最左边。
元素 4 和 3 大于 pivot ,所以它们在数组的最右边。
小于 pivot 的元素的相对位置和大于 pivot 的元素的相对位置分别为 [-3] 和 [4, 3] ,它们在结果数组中的相对顺序需要保留。
提示:
1 <= nums.length <= 10^5-10^6 <= nums[i] <= 10^6pivot等于nums中的一个元素。
解题思路
思路一:三路分区
这类 稳定排序 问题适合 三路分区(Three-way partitioning),即:
- 维护 三个列表:
less:存放 小于pivot的元素。same:存放 等于pivot的元素。greater:存放 大于pivot的元素。
- 遍历
nums,根据num的大小,放入对应的列表。 - 最终 按顺序拼接:
less + same + greater。
复杂度分析
- 时间复杂度:
O(n),遍历数组一次,拼接O(n)。 - 空间复杂度:
O(n),使用了额外的数组存储分类数据。
思路二:双指针
- 第一遍遍历:统计
pivot出现的次数sameCount,并计算 小于pivot的元素的数量,用lessCount记录。 - 第二遍遍历:
- 前
lessCount位置填充 小于pivot的元素。 - 接下来
sameCount个位置填充pivot。 - 最后填充 大于
pivot的元素。
- 前
复杂度分析
- 时间复杂度:
O(n),遍历数组两次。 - 空间复杂度:
O(n),O(1)额外空间,避免了less/same/greater额外数组,更节省内存。
代码
/**
* @param {number[]} nums
* @param {number} pivot
* @return {number[]}
*/
var pivotArray = function (nums, pivot) {
let less = [],
same = [],
greater = [];
for (let num of nums) {
if (num < pivot) {
less.push(num);
} else if (num > pivot) {
greater.push(num);
} else {
same.push(num);
}
}
return less.concat(same, greater);
};
/**
* @param {number[]} nums
* @param {number} pivot
* @return {number[]}
*/
var pivotArray = function (nums, pivot) {
let result = [];
let sameCount = 0;
let lessCount = 0;
// 计算 pivot 出现的次数,并填充小于 pivot 的数
for (let num of nums) {
if (num < pivot) {
result.push(num);
lessCount++;
} else if (num == pivot) {
sameCount++;
}
}
// 填充 pivot
while (sameCount > 0) {
result.push(pivot);
sameCount--;
}
// 填充大于 pivot 的数
for (let num of nums) {
if (num > pivot) {
result.push(num);
}
}
return result;
};
相关题目
| 题号 | 标题 | 题解 | 标签 | 难度 | 力扣 |
|---|---|---|---|---|---|
| 86 | 分隔链表 | [✓] | 链表 双指针 | 🟠 | 🀄️ 🔗 |
| 2149 | 按符号重排数组 | 数组 双指针 模拟 | 🟠 | 🀄️ 🔗 |
