This commit is contained in:
krahets
2023-08-27 23:40:56 +08:00
parent 48980ddf28
commit df0f7d3be1
64 changed files with 255 additions and 261 deletions
+3 -3
View File
@@ -325,13 +325,13 @@ comments: true
细心的同学可能发现,**如果输入数据是对象,上述步骤 `3.` 就失效了**。假设输入数据是商品对象,我们想要按照商品价格(类的成员变量)对商品进行排序,而上述算法只能给出价格的排序结果。
那么如何才能得到原数据的排序结果呢?我们首先计算 `counter` 的“前缀和”。顾名思义,索引 `i` 处的前缀和 `prefix[i]` 等于数组前 `i` 个元素之和,即
那么如何才能得到原数据的排序结果呢?我们首先计算 `counter` 的“前缀和”。顾名思义,索引 `i` 处的前缀和 `prefix[i]` 等于数组前 `i` 个元素之和:
$$
\text{prefix}[i] = \sum_{j=0}^i \text{counter[j]}
$$
**前缀和具有明确的意义,`prefix[num] - 1` 代表元素 `num` 在结果数组 `res` 中最后一次出现的索引**。这个信息非常关键,因为它告诉我们各个元素应该出现在结果数组的哪个位置。接下来,我们倒序遍历原数组 `nums` 的每个元素 `num` ,在每轮迭代中执行
**前缀和具有明确的意义,`prefix[num] - 1` 代表元素 `num` 在结果数组 `res` 中最后一次出现的索引**。这个信息非常关键,因为它告诉我们各个元素应该出现在结果数组的哪个位置。接下来,我们倒序遍历原数组 `nums` 的每个元素 `num` ,在每轮迭代中执行以下两步。
1. 将 `num` 填入数组 `res` 的索引 `prefix[num] - 1` 处。
2. 令前缀和 `prefix[num]` 减小 $1$ ,从而得到下次放置 `num` 的索引。
@@ -775,7 +775,7 @@ $$
## 11.9.3   算法特性
- **时间复杂度 $O(n + m)$** :涉及遍历 `nums` 和遍历 `counter` ,都使用线性时间。一般情况下 $n \gg m$ ,时间复杂度趋于 $O(n)$ 。
- **空间复杂度 $O(n + m)$ 、非原地排序** :借助了长度分别为 $n$ 和 $m$ 的数组 `res` 和 `counter` 。
- **空间复杂度 $O(n + m)$、非原地排序**:借助了长度分别为 $n$ 和 $m$ 的数组 `res` 和 `counter` 。
- **稳定排序**:由于向 `res` 中填充元素的顺序是“从右向左”的,因此倒序遍历 `nums` 可以避免改变相等元素之间的相对位置,从而实现稳定排序。实际上,正序遍历 `nums` 也可以得到正确的排序结果,但结果是非稳定的。
## 11.9.4   局限性