1. 题目来源
链接:41. 缺失的第一个正数
2. 题目解析
拿哈希表或者排序来做,这题应该是 Easy
。若要求空间复杂度
O
(
1
)
O(1)
O(1) 才能称之为 Hard
。本题和剑指 offer
中有一道题很像,可见之前的博文:[剑指-Offer] 3. 数组中重复的数字(哈希、抽屉原理、代码优化、多方法)。按理说考查的是抽屉原理,将空间复杂度也优化到
O
(
1
)
O(1)
O(1)。
答案必定在 1~n
里面,则我们可以将数组中的数字放到其对应的位置上去,即数字 1 放到 下标 0 的位置上去,数字 3 放到下标 2 的位置上去。这样做,就能恢复这个数组,也就是抽屉原理。放法和 [剑指-Offer] 3. 数组中重复的数字(哈希、抽屉原理、代码优化、多方法) 一样。不再赘述。
细节:
- 负数不用处理,不要一上来就给所有数字减 1,这个
INT_MIN - 1
简直就是天坑。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:哈希
O
(
n
)
O(n)
O(n),抽屉原理优化后
O
(
1
)
O(1)
O(1)
代码:
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
unordered_set<int> hash;
for (auto x : nums) hash.insert(x);
int res = 1;
while (hash.count(res)) res ++ ;
return res;
}
};
// 抽屉原理优化
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
for (int i = 0; i < n; ++i) {
while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
swap(nums[nums[i] - 1], nums[i]);
}
}
for (int i = 0; i < n; ++i) {
if (nums[i] != i + 1) {
return i + 1;
}
}
return n + 1;
}
};