题目

暴力
思路:从 1 开始枚举正整数,逐个遍历数组判断是否存在,返回第一个不存在的数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class SolutionBrute { public: int firstMissingPositive(vector<int>& nums) { int n = nums.size();
for (int x = 1; x <= n + 1; ++x) { bool found = false;
for (int num : nums) { if (num == x) { found = true; break; } }
if (!found) return x; }
return n + 1; } };
|
时间复杂度:O(n2)
空间复杂度:O(1)
优化
思路: 用哈希集合记录数组中的元素,再从 1 到 n + 1 查找第一个未出现的正整数。
1 2 3 4 5 6 7 8 9 10 11 12 13
| class SolutionHash { public: int firstMissingPositive(vector<int>& nums) { unordered_set<int> s(nums.begin(), nums.end()); int n = nums.size();
for (int x = 1; x <= n + 1; ++x) { if (!s.count(x)) return x; }
return n + 1; } };
|
时间复杂度:O(n)
空间复杂度:O(n)
最优
思路: 将合法数字 x 放到下标 x - 1 的位置,整理后扫描数组,首个位置不满足 nums[i] == i + 1 时,i + 1 即为答案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public: int firstMissingPositive(vector<int>& nums) { int n = nums.size();
for (int i = 0; i < n; ++i) { while ( nums[i] >= 1 && nums[i] <= n && nums[nums[i] - 1] != nums[i] ) { swap(nums[i], nums[nums[i] - 1]); } }
for (int i = 0; i < n; ++i) { if (nums[i] != i + 1) { return i + 1; } }
return n + 1; } };
|
时间复杂度:O(n)
空间复杂度:O(1)