版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jining11/article/details/82726492
其实看到这种hard类型的题目,还是有点紧张的,但有惊无险,一次就过了。
题目描述
Given an unsorted integer array, find the smallest missing positive integer.
大意就是说,给你一堆毫无规则的正数,你要给出其中不包含的正数里面最小的那一个。
额外建立数组法
一开始我其实想到了那个查找第K大元素的典型问题,但是排序似乎太浪费时间了,毕竟我们只是要检验一种存在性,而不是获得一种有序性,那么如何验证一个元素的存在呢,一个简单的方法是将数组里这个元素出现的位置置一,而把其他位置置为零。除此之外,由于数据的连续性特征,数组的大小只需设置为给出的元素的数目即可。
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int * x = new int[nums.size()]();
for (int i = 0; i < nums.size(); i++) {
if (nums[i] > 0 && nums[i] <= nums.size()) {
x[nums[i]-1] = 1;
}
}
int result = nums.size()+1;
for (int i = 0; i < nums.size(); i++) {
if (!x[i]) {
result = i+1;
break;
}
}
delete [] x;
return result;
}
};
临交的时候我才发现题目里面有这么一句话:
Your algorithm should run in O(n) time and uses constant extra space.
由于要新申请数组,所以我所需的额外空间是O(n)级别而非O(1)常量级。
试着交了一下,居然过了,但还是想试试有没有符合要求的解法。
就地修改交换法
既然所开辟新数组的大小恰恰与给出的元素一致,那为什么不在原来的基础上修改呢?
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[i], nums[nums[i] - 1]);
for(int i = 0; i < n; ++ i)
if(nums[i] != i + 1)
return i + 1;
return n + 1;
}
};