缺失的第一个正数

思路:我的初步想法是先对数组排序,然后找到第一个正数的位置,从1开始顺序比对:哪个没出现就是答案。

代码:


class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int ans=0;
        int zs_poition=0;
        for(int i=0;i<nums.size();i++)
        {
            if(nums[i]>0)
            {
                zs_poition=i;//第一个正整数的位置,从这里开始比对
                break;
            }
        }
        for(int i =zs_poition,zzs=1;i<nums.size();i++)
        {
            
            if(zzs!=nums[i])
            {
                ans=zzs;
                break;
            }
            if(i==nums.size()-1)
            {
                ans=zzs+1;
            }
            zzs++;
        }
        return ans;
    }
};

巨呆逼的方法 还错了。。。。。。。

        分析了一下错误样例,原因就是没有考虑重复数字,可以排序后进行一次去重。也可以在后面专门处理一下有重复数字的情况。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int ans=0;
        int zs_poition=0;
        for(int i=0;i<nums.size();i++)
        { 
            if(nums[i]>0)
            {
                zs_poition = i;//第一个正整数的位置,从这里开始比对
                break;
               
            }
        }
        for(int i =zs_poition,zzs=1;i<nums.size();i++)  
        {
            // 处理重复数字            
            if(zzs!=nums[i])
            {
                if(i==0)
                {
                    ans=zzs;
                    break;
                }
                else if(i>0&&nums[i]!=nums[i-1])
                {
                    ans=zzs;
                    break;
                }
                else
                {
                    zzs--;
                }
            }
            if(i==nums.size()-1)
            {
                ans=zzs+1;
            }
            
            zzs++;
        }
        return ans;
    }
};

现在是全部过了。但是用了排序,算是作弊了吧,排序是nlogn    题目要求时间复杂度On,且常数级别的空间复杂度。

看看题解:

都太巧妙了。

我们用排序的也太复杂了:

这样不用考虑重复的问题。但是都是不满足O(n)或者另外开了空间的。

但我们也来写一些代码来练一下手吧。

法一:哈希表

注意 哈希表的增加元素是用insert()方法。

这里用一个简单的set就可以了,只要存键。
 

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        unordered_set<int> q;
        for(auto t:nums)
        {
            q.insert(t);
        }
        for(int i=1;;i++)
        {
            if(!q.count(i))
            {
                return i;
            }
        }
    }
};

法二On^2就算了

实在是太妙了下面这个解法,一定要温故而知新:

 主要思路:

        要明白,缺失的正整数一定在[1,N+1]中,其中N 为数组的长度。

这道题的灵感就是从哈希表中得到的,可以对数组进行标记。

        首先,由于缺失的正整数一定在[1,N+1]中:若[1,N]都存在,则缺失的为N+1,否则,缺失的正整数就在[1,N]中。

        首先,对数组中小于1的数进行赋值,就赋值为N+1即可。

        然后遍历一次数组,将遍历到的值在[1,N]中的对应位置加上负号(打上标记),代表这个位置所代表的正整数是在数组中存在的。

        由于会出现负数,(被标记过了),故在进行遍历的时候,取绝对值来判断。

最后,再遍历一遍数组,若所有的位置都被打上了标记(全部为负数),则第一个缺失的正整数即为N+1。

这样子写的代码就是O(n)且没有开其他的空间。

代码:

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n =nums.size();
        for(int i=0;i<n;i++)
        {
            if(nums[i]<1)
            {
                nums[i]=n+1;//处理一下本来的负数和0,以免影响标记
            }
        }
        for(int i=0;i<n;i++)//遍历整个数组
        {
            int t=abs(nums[i]);
            if(t>=1&&t<=n)
            {
                nums[t-1]=-abs(nums[t-1]);//如果满足要求,将对应位置改为负数,已经是负的不用再处理一次。
            }
        }
        int ans=0;
        for(int i=0;i<n;i++)//重新遍历
        {
            if(nums[i]>0)//有大于零的  则i+1则为缺的那个正整数
            {
                ans=i+1;
                break;
            }
        }
        return ans==0?n+1:ans;//若ans还是等于0,则代表1~N在数组中都有,缺失的正整数为N+1;
        

    }
};

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值