题目:
Given an unsorted integer array, find the first missing positive integer.
For example,
Given [1,2,0]
return 3
,
and [3,4,-1,1]
return 2
.
Your algorithm should run in O(n) time and uses constant space.
思路:
方法1:通过bitmap或者哈希函数遍历数组一次并且记录所有的正数,从1开始找到bitmap或者哈希函数中不存在的第一个正数。 方法2:为了节省空间,我们需要考虑bitmap或者hash table的空间需要。根据抽屉原理,当我们有长度为n的数据(n个抽屉)的时候,消失的数总是在1到n+1之间,所以我们只需要用n+1长度的hash table来存储。另外,由于数组已经有n位,我们其实可以将对应的数直接hash到对应的位置存储即可。例如数据2放到2-1这个位置。最后遍历一次发现某个位置的索引与存储的值不相匹配的时候就找到了消失的第一次正数。
代码:
方法1:
class bitmap {
public: bitmap(int n);~bitmap();
void set(int k);
bool val(int k);
private: int len;
unsigned int * map;
unsigned int * reversemap;
bool zero;
};
bitmap::bitmap(int n)
{
len = n/32+1;
map = new unsigned int[len];
reversemap = new unsigned int[len];
for(int i = 0; i < len; i++)
{
map[i] = 0;
reversemap[i] = 0;
zero = false;
}
}
void bitmap::set(int k)
{
bool reverse = true;
if(k== 0)
{
zero = true;
}
else if(k<0)
{
reverse = false;
k =-k;
}
int a = k/32;
int b = k%32;
if(a >= len)
{
return;
}
else
{
if(reverse)
{
unsigned int tmp = reversemap[a]/pow(2,b);
if(tmp%2 == 0)
{
reversemap[a] += pow(2,b);
}
}
else
{
unsigned int tmp = map[a]/pow(2,b);
if(tmp%2 == 0)
{
map[a] += pow(2,b);
}
}
}
}
bool bitmap::val(int k)
{
bool reverse = true;
if(k== 0)
{
return zero;
}
else if(k<0)
{
reverse = false;
k =-k;
}
int a = k/32;
int b = k%32;
if(a >= len)
{
return false;
}
else
{
if(reverse)
{
unsigned int tmp = reversemap[a]/pow(2,b);
if(tmp%2 == 1)
{
return true;
}
else
{
return false;
}
}
else
{
unsigned int tmp = map[a]/pow(2,b);
if(tmp%2 == 1)
{
return true;
}
else
{
return false;
}
}
}
}
class Solution {
public:
int firstMissingPositive(int A[], int n) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
bitmap * bm = new bitmap(1000);
for(int i = 0; i < n; i++)
{
if(A[i] > 0)
{
bm->set(A[i]);
}
}
for(int i = 1;;i++)
{
if(!bm->val(i))
{
return i;
}
}
}
};
方法2:
class Solution {
public:
int firstMissingPositive(int A[], int n) {
for(int i = 0; i < n; i++){
int val = A[i];
if(val > 0 && val <= n && A[val - 1] != val){
swap(A[i],A[val - 1]);
i--;
}
}
for(int i = 0; i < n; i++){
if(A[i] != i+1){
return i + 1;
}
}
return n + 1;
}
};