LeetCode #41 First Missing Positive 数组
Description
Given an unsorted integer array, find the smallest missing positive integer.
Example 1:
Input: [1,2,0]
Output: 3
Example 2:
Input: [3,4,-1,1]
Output: 2
Example 3:
Input: [7,8,9,11,12]
Output: 1
Note:
- Your algorithm should run in O(n) time and uses constant extra space.
思路
解法一
题目要让我们找出一个数组中缺失的最小正整数。
通过分析发现,对于一个长度为 n 的数组,它缺失的最小正整数只能是 [1, 2, ..., n] 中的一个。
因此,创建一个 HashSet 并存入 nums 中所有元素的值,遍历从 1 到 n ,找到第一个缺失的正整数,就是 nums 中缺失的最小正整数。
时间复杂度:拷贝到set O(n) + 找出缺失的最小正整数 O(n) = O(n)
空间复杂度:开辟一个 nums.size 大小的 set O(n) = O(n)
耗时 8 ms, 占用空间 6.8 MB, ranking 50%
class Solution {
public:
int firstMissingPositive(const vector<int> &nums) {
if (nums.empty()) return 1;
unordered_set<int> nums_set(nums.cbegin(), nums.cend());
// for an array, min positive seq is [1, 2, ..., nums.size()]
// so the missing positive must be one of them
int i = 1;
while (i <= nums.size()) {
if(nums_set.find(i) == nums_set.end()) {
break; // find the min missing positive
} else {
++i;
}
}
return i;
}
};
解法二
思路还是和解法一相同,但是需要进一步压缩space。
想要实现 O(1) 时间复杂度的访问与修改,以及 O(1) 的存储空间,还是需要数组的支持,而且只能基于原数组进行增删改查。
因为缺失的正整数一定是 [1, 2, ..., n] 中的一个,所以我们可以遍历 nums,把值在 [1, n] 范围内的移动到数组 [0, n-1] 的位置上,以便用 O(1) 的空间找到缺失的最小正整数。
时间复杂度:移动操作 O(n) + 找出缺失的最小正整数 O(n) = O(n)
空间复杂度:原址修改 O(1)
耗时为 4 ms, 占用空间 6.5 MB, ranking 55%
class Solution {
public:
int firstMissingPositive(vector<int> &nums) {
if (nums.empty()) return 1;
// for an array, min positive seq is [1, 2, ..., nums.size()]
// so the missing positive must be one of them
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] > 0 && nums[i] <= nums.size()) {
if (nums[nums[i] - 1] == nums[i]) {
continue;
}
swap(nums[nums[i] - 1], nums[i]);
--i; // check swaped element in current position
}
}
// compare with the min positive seq [1, 2, ..., nums.size()]
int i = 1;
while (i <= nums.size()) {
if (nums[i-1] == i) {
++i;
} else {
break; // find the min missing positive
}
}
return i;
}
};
参考
- 《[LeetCode] 41. First Missing Positive 首个缺失的正数》:https://www.cnblogs.com/grandyang/p/4395963.html
————全心全意投入,拒绝画地为牢