美文网首页
41. First Missing Positive

41. First Missing Positive

作者: codingXue | 来源:发表于2017-03-23 10:18 被阅读175次

    问题描述

    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.

    问题分析

    这是一道hard题,自己没有思路TAT,在网上搜了解答

    分析题意

    • 要找的是第一个不存在的正数,那么对于长度为n的输入,非正数和大于n的数都是没有用的。
    • 要求用常数空间解决,因此不能另开数组,而应该在原数组上进行操作,这时应留意到,数组的下标是0到n-1,与我们考虑的正数范围1到n是一一对应的。
    • 我们利用下标作为标记,将数组中每个在1到n之间的元素item,放在nums[item-1]的位置,然后第二次遍历数组,找到第一个nums[i] != i+1的位置,则i+1就是我们要找的first missing postive integer。

    做法

    1. 第一次遍历数组,若nums[i]的值在1,n之间且nums[nums[i]-1] != nums[i],则交换nums[nums[i]-1]和nums[i]。nums[nums[i]-1] != nums[i]包含两层含义,1)如果nums[i] != i+1,则nums[i]-1 != i,那么nums[i]需要被调换到它应该去的位置;如果nums[nums[i]-1] == nums[i]说明待交换的两个数字相等,则不需交换,否则会死循环。需要注意的是,如果被换到nums[i]位置的数字依然符合交换条件,那么需要继续进行交换,也就是说这里不是一个if判断,而是一个while循环。
    2. 第二次遍历数组,找到第一个nums[i] != i+1的位置,返回i+1。

    复杂度分析
    虽然这个思想还是蛮好理解,但是在一个for循环里又出现了一个while循环,它的复杂度能是O(n)吗?其实是酱紫,算法复杂度应该看的是基本操作的次数,在这个问题里,基本操作指的是交换操作,而每次交换操作,都至少有一个数字去了它应该去的地方,那么一个n长度的数组,最多只需要n次交换操作,所以它的复杂度是O(n)的~

    AC代码

    class Solution {
    public:
        int firstMissingPositive(vector<int>& nums) {
            int n = nums.size();
            int i;
            for (i = 0; i < n; i++){
                while(nums[i] > 0 && nums[i] < n && nums[nums[i]-1] != nums[i]){
                    int tmp = nums[nums[i]-1];
                    nums[nums[i]-1] = nums[i];
                    nums[i] = tmp;
                }
            }
            for (i = 0; i < n; i++){
                if (nums[i] != i+1)
                    break;
            }
            return i+1;
        }
    };
    

    Runtime: 3 ms, which beats 70.66% of cpp submissions.

    相关文章

      网友评论

          本文标题:41. First Missing Positive

          本文链接:https://www.haomeiwen.com/subject/dfkznttx.html