4065. 移除不同值重排数组
难度简单
题目描述
给你一个整数数组 nums。
初始时,你有一个 空 数组 ans。重复执行以下操作,直到 nums 变为 空 :
- 找出当前
nums中 所有不同 的值。 - 将当前
nums中每个 不同 的值各移除一个,并按 升序 将这些值依次添加到ans中。
返回数组 ans。
示例 1:
输入: nums = [3,1,3,2,1,3]
输出: [1,2,3,1,3,3]
解释:
| 操作 | 添加到 ans 的值 | 操作后的 nums | 操作后的 ans |
|---|---|---|---|
| 1 | 1, 2, 3 | [3, 1, 3] | [1, 2, 3] |
| 2 | 1, 3 | [3] | [1, 2, 3, 1, 3] |
| 3 | 3 | [] | [1, 2, 3, 1, 3, 3] |
此时 nums 已为空,因此答案为 [1, 2, 3, 1, 3, 3]。
示例 2:
输入: nums = [7,7,4,4,4]
输出: [4,7,4,7,4]
解释:
| 操作 | 添加到 ans 的值 | 操作后的 nums | 操作后的 ans |
|---|---|---|---|
| 1 | 4, 7 | [7, 4, 4] | [4, 7] |
| 2 | 4, 7 | [4] | [4, 7, 4, 7] |
| 3 | 4 | [] | [4, 7, 4, 7, 4] |
此时 nums 已为空,因此答案为 [4, 7, 4, 7, 4]。
提示:
1 <= nums.length <= 1001 <= nums[i] <= 100
解法
方法一:计数
思考
\(n\) 和每个元素都不超过 \(100\),按题意一轮轮取出剩余的不同值是来得及的。每一轮都要收集当前还在的值并按升序各删一个,若直接在原数组里查找再删除,下标会不断挪动。
一个值被取走的次数就是它的出现次数,每一轮内部的先后只由数值大小决定,与原来的下标无关。
因此先按值计数。值域是 \([1,m]\),从小到大扫描,次数仍为正就写入答案并减一。外层重复到答案长度等于 \(n\),每一遍扫描对应一轮操作。
设 \(m=\max(\textit{nums})\), \(\textit{cnt}[x]\) 为值 \(x\) 的出现次数。第 \(k\) 轮(从 \(0\) 计)按升序取走所有当时仍有剩余的值,也就是最初出现次数大于 \(k\) 的那些值。
用长度为 \(m+1\) 的数组记下次数。答案还不满 \(n\) 个元素时,把 \(x\) 从 \(1\) 扫到 \(m\): \(\textit{cnt}[x]>0\) 就把 \(x\) 追加进答案,并把次数减一。一轮扫描对应一次操作,追加的顺序就是升序。
时间复杂度 \(O(nm)\),空间复杂度 \(O(m)\)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |