本文已参与「新人创作礼」活动,一起开启掘金创作之路。
消失的两个数字
示例 1:
输入: [1]
输出: [2,3]
示例 2:
输入: [2,3]
输出: [1,4]
思路
一共有n个数,我们缺少了两个数
形如:
1 0 0 2 3 4 5 6
这里的 0 代表的是 缺少的数
如何找到这两个缺少的数呢?
我的做法是排序!
但是一般的排序达不到这个要求
我们需要考虑一种O(n)的排序
当你读到这里,肯定会说,不可能,时间复杂度最低的排序算法是O(nlogn)
但是,我们的数据特殊一些
就导致了不一样的结构
下面我们来看看我的排序做法
这种做法利用的值域特别小的特点
假设当前的0,我们给他添加到末尾
然后我们就得到了这样一个数列
3 1 2 5 7 0 0
此时我们首先对第一个数进行操作
发现他并不等于他本身,于是我们做一次交换操作
2 1 3 5 7 0 0 // 交换 3到3的下标位置
然后,我们继续处理第一个数,当前为2
1 2 3 5 7 0 0 // 交换 2到2的下标位置
第一个数交换完毕,第二个数和第三个数也排好序了
然后,我们 对第四个数进行操作
1 2 3 7 5 0 0 // 同理交换
然后,对第四个数,交换到第七个位置
1 2 3 0 5 0 7 // 同理交换
此时,我们的数组就被神奇的交换好了!
也找出来了两个缺少的数,可能有的人就有疑问,为什么一定保证可以排好序呢?
不会出现这种情况吗?
1 0 3 2
走过了这个数,但是 0 却留着了前面
请注意,这里,若是当前这个数是存在的,总会被交换到对应位置
就可以一步一步的把0逼到对应没有的位置
也可以说,这是一种哈希吧。
代码
class Solution {
public:
vector<int> missingTwo(vector<int>& nums) {
vector<int> res;
nums.push_back(0), nums.push_back(0);
for (int i = 1; i <= nums.size(); i ++)
while (nums[i-1] != i && nums[i-1])
swap(nums[i-1], nums[nums[i-1]-1]);
for (int i = 1; i <= nums.size(); i ++)
if (i != nums[i-1]) res.push_back(i);
return res;
}
};