41. First Missing Positive

7 篇文章 0 订阅
6 篇文章 0 订阅

Task:

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.

Some Questions:

What's the length of the array?

What's the range of the element?

Can I modify the array?

Solution:

//enumerate O(n^2)+O(1)

At first glance, I thought out a brute force algorithm: enumerate positive integer and check whether it is in the array. 

Above algorithm runs in O(n^2) time complexity and O(1) space complexity. It doesn't meet the restriction of time complexity.
//radix-sort, O(n)+O(1<<16),

After a while, I realized that I should sort the array, I used radix-sort, then traverse the array to find the answer.

However radix-sort uses O(n) time and O(1<<16) space. I doubt whether O(1<<16) space is constant space.
//quick sort, O(nlogn)+O(1)

Another sort algorithm is quick sort, but the time complexity is O(nlogn) which doesn't meet the restriction.

At last, I realized that I can use "group sort" , 

step 1:  remove non-positive element and the element larger than n (here n is the size of the array).

step 2: traverse the array, for the position nums[i]!=i, do follow operations

<span style="white-space:pre">		</span>int tmp=nums[i];
                nums[i]=-1;
                while(tmp>=1&&tmp<=n)
                {
                    swap(nums[tmp],tmp);
                    if(nums[tmp]==tmp)break;
                }

step 3: traverse the array, find the first position which nums[i]!=i, return the answer.

In this algorithm, the main complexity is in step 2. Because every element is in [1,n], so for group theory, every element will belong to one group, every element will be visited two times (one for array traverse and one for group traverse ).

So the algorithm runs in O(n) time complexity and O(1) time space perfectly.

More detail for group theory:Group_Theory from wiki

 

Code:

//enumerate O(n^2)+O(1)
//radix-sort, O(n)+O(1<<16),
//quick sort, O(nlogn)+O(1)
//group sort, O(n)+O(1)

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n=nums.size();
        if(nums.size()==0)return 1;
        int i,j=0;
        for(i=0;i<n;i++)
        {
            if(nums[i]>0)
            {
                nums[j++]=nums[i];
            }
        }
        nums.erase(nums.begin()+j,nums.end());
        
        n=nums.size();
        
        nums.insert(nums.begin(),0);
        
        for(i=1;i<=n;i++)
        {
            if(nums[i]==-1)continue;
            else if(nums[i]!=i+1)
            {
                int tmp=nums[i];
                nums[i]=-1;
                while(tmp>=1&&tmp<=n)
                {
                    swap(nums[tmp],tmp);
                    if(nums[tmp]==tmp)break;
                }
            }
        }
        for(i=1;i<=n;i++)
        {
            if(nums[i]!=i)break;
        }
        return i;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值