leetCode (41)--First Missing Positive

这道题,我的思路大致如下:
首先对数组进行排序,设置一个计数为i,记录已经出现的正整数数目,依次遍历排序后的数组,判断大于0的元素是否等于i,若不等于可以判断为缺少的最小正整数就是i;要考虑的特殊情况是有重复数字出现和最后一位元素的判断。若与前一位数字相同,则继续下一次遍历,i不递增,特殊的如果最后一位是重复的,直接返回i;若判断到最后一位,返回i+1。如果不是特殊情况,i递增,继续遍历。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {

        sort(nums.begin(),nums.end());

        if(nums.size()==0)return 1;
        if(nums.size()==1){
            if(nums[0]!=1)return 1;
            else return 2;
        }
        int i=1;
        for(int j=0;j<nums.size();j++)
        {

            if(nums[j]>0)
            {
                if(nums[j]!=i)
                {
                   if((nums[j]<i)&&j!=nums.size()-1)continue; //和前一位重复,且不是最后一位
                    else return i;
                }
                else 
                {
                   if(j==nums.size()-1)return i+1; //当遍历到最后一位
                   if(nums[j]!=nums[j-1]) i++;
                }
            }

        }
    }
};

这种方法容易想到,但是总是有一些没考虑的情况,要通过测试数据添加。在网上看到了其他人的做法,还是太笨呀,在此也记录下来。
虽然不能再另外开辟非常数级的额外空间,但是可以在输入数组上就地进行swap操作。
思路:交换数组元素,使得数组中第i位存放数值(i+1)。最后遍历数组,寻找第一个不符合此要求的元素,返回其下标。整个过程需要遍历两次数组,复杂度为O(n)。
下图以题目中给出的第二个例子为例,讲解操作过程。
这里写图片描述
n个元素的数组,里面的数都是0~n-1范围内的,求数组中重复的某一个元素,没有返回-1, 要求时间性能O(n) 空间性能O(1)。

实现代码如下:

public class Solution {
    public int firstMissingPositive(int[] nums) {
        if(nums.length == 0)
            return 1;
        //第i位存放i+1的数值
        for(int i = 0; i < nums.length;i++){
            if(nums[i] > 0){//nums[i]为正数,放在i+1位置
                //如果交换的数据还是大于0且<i+1,则放在合适的位置,且数据不相等,避免死循环
                //这个while是关键,其他都是没有难度的
                while(nums[i] > 0 && nums[i] < i+1 && nums[i] != nums[nums[i] -1]){
                    int temp = nums[nums[i]-1];//交换数据
                    nums[nums[i]-1] = nums[i];
                    nums[i] = temp;
                }
            }
        }
        //循环寻找不符合要求的数据,返回
        for(int i = 0; i < nums.length;i++){
            if(nums[i] != i+1){
                return i+1;
            }
        }
        //如果都符合要求,则返回长度+1的值
        return nums.length + 1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值