标签:insert n+1 出现 fir 正数 code 第一个 说明 iss
41 缺失的第一个正数
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
示例 1:输入: [1,2,0]输出: 3
示例 2:输入: [3,4,-1,1]输出: 2
示例 3:输入: [7,8,9,11,12]输出: 1
提示:你的算法的时间复杂度应为O(n),并且只能使用常数级别的额外空间。
思路1:
hash 表, 从小到大枚举检查1 ~ nums.size()是否在数组中存在,如果不存在则说明我们找到了最小的不存在数字。
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
unordered_set<int> nums_set;
for(int n : nums) nums_set.insert(n);
for(int i = 1; i <= nums.size(); i++)
if(!nums_set.count(i)) return i;
return nums.size() + 1;
}
};
思路2:先排序再找
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
sort(nums.begin(), nums.end());
int ans = 1;
for(int num : nums){
if(num == ans)
ans++;
}
return ans;
}
};
思路3:利用原数组哈希
我们考虑使用原数组实现哈希表。我们将映射公式设为nums[i] = i+1。
即下标为0,存放1;下标为1,存放2......假设nums数组长度为n,那么最后的答案应该在[1,n+1]范围内,且只有当nums为存放的为1-n内的所有正整数时,答案才为n+1。
我们遍历nums,判断nums[i],当它的值范围在[1,n]中,就将它与nums[nums[i]-1]进行互换,
此时还需要判断nums[nums[i]-1]是不是与nums[i]已经相等了,这时就是遇到了重复的元素,pass。
遍历完之后,我们再一次遍历更改后的nums数组,当nums[i] != i+1,返回i+1即可,若遍历结束之后没有返回,返回n+1即可。
也就是,第一次遍历将数据归位,
第二次遍历检查,谁缺失了即可
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[i] != nums[nums[i]-1])
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;
}
};
标签:insert n+1 出现 fir 正数 code 第一个 说明 iss
原文地址:https://www.cnblogs.com/Allen-rg/p/13920348.html