LeetCode 41. 缺失的第一个正数

  • 题目:41. 缺失的第一个正数
    给定一个未排序的整数数组,找出其中没有出现的最小的正整数。
  • 示例 1:
    输入: [1,2,0]
    输出: 3
  • 示例 2:
    输入: [3,4,-1,1]
    输出: 2
  • 示例 3:
    输入: [7,8,9,11,12]
    输出: 1
  • 说明:
    你的算法的时间复杂度应为O(n),并且只能使用常数级别的空间。
  • 思路1:
    把数组变成“理想情况”的状态,即{1,2,3,4,5,…},然后循环遍历数组,直到A[i]!=i+1的时候,便找到了最小的正整数i+1。
/*
    * 思路真是巧妙啊~不得不赞,绝了
    *
    * */
    public int firstMissingPositive(int[] A) {
        int i = 0;
        while (i < A.length) {
            /*
            * 我们知道最小正整数肯定在[1,n+1]中
            * 理想情况是这样的{1,2,3,4,5}
            * 我们现在就把数组A转换成理想情况,位置i的值应该是i+1。如果值<=0||值>A.length,也视为理想情况
            * */
            if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) i++;
            /*
            * 如果i位置上的数不是理想情况的值,那么看看,值为i的理想位置上的数值是不是i
            *   如果不是的话,则交换位置,把i值放到正确的位置上;
            *   否则i++,检查下一个位置
            * */
            else if (A[A[i] - 1] != A[i]) swap(A, i, A[i] - 1);
            else i++;
        }
        i = 0;
        while (i < A.length && A[i] == i + 1) i++;
        return i + 1;
    }

    private void swap(int[] A, int i, int j) {
        int temp = A[i];
        A[i] = A[j];
        A[j] = temp;
    }
  • 思路2
/*
    * 题目要求:用常数级别的额外空间,这个可能不符合要求,因为用到了Arrays.sort(nums);
    * 思路:
    * 首先,排序
    * 然后,找到第一个是正数的位置,从该位置开始,找出最小的正整数
    * */
    public int firstMissingPositive1(int[] nums) {
        //注意:别忘了判断
        if (nums == null || nums.length == 0)
            return 1;

        Arrays.sort(nums);

        //找到第一个正整数的位置
        int i = 0;
        while ((i < nums.length) && nums[i] <= 0) {
            i++;
        }

        //找到未出现的最小的正整数
        int min = 1;
        for (; i < nums.length; i++) {
            //目的是:前一个正数和当前正数重复的话,继续判断,不做处理
            if (i > 0 && nums[i - 1] > 0 && nums[i - 1] == nums[i]) {
                continue;
            }
            if (nums[i] > min) {
                return min;
            } else {
                min++;
            }
        }
        return min;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值