一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情。
题目描述
给你一个未排序的整数数组 nums
,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n)
并且只使用常数级别额外空间的解决方案。
思路分析
如果是不考虑O(n)时间复杂度的话,我们可以通过排序来解决,如果不考虑常数级别空间复杂度,我们也可以将元素扔入单调栈或堆中,但是在目前的要求下就不能使用以上方案了。
不过这些方案有一些共同点,其实或有或无的想去排序,也很好理解,我们可以通过排序更容易的找到最小的正数。
这道题本身也有个条件,我们假设对于元素,只存在0-n,去找到缺失的最小的正数(因为有0,所以必存在最小的正数或n+1)。
那如果元素不是0-n,说明结果必然在0-n中,所以我们只需要对元素大小为0-n的元素进行排序即可。
大多数排序很难O(n)时间复杂度,是因为结果集并不是有限制的,但是在结果集限制的条件下,我们可以通过交换排序,实现一种O(n)时间复杂度的排序。
具体实现
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;
}
总结
这道题本身难度并不是很大,只能说交换这种思路不好想,不过只要做过一次就没问题了。