• 【LeetCode】41. First Missing Positive (3 solutions)


    First Missing Positive

    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.

    解法一:O(nlogn) time and O(1) space

    无脑解法-->先排序O(nlogn)

    思想如下:

    1、略去非正的前缀数。

    2、记下一个待匹配的正整数为tag。

    考虑重复,如果A[i]等于tag,则tag++

    如果A[i]大于tag,则返回tag

    A[i]不可能小于tag,由排序可以保证。

    class Solution {
    public:
        int firstMissingPositive(int A[], int n) {
            if(n == 0)
                return 1;
            sort(A,A+n);
            int i = 0;
            while(i < n && A[i] <= 0)
                i ++;
            if(i == n)
                return 1;
            int tag = 1;
            for(; i < n; i ++)
            {
                if(A[i] > tag)
                //miss the tag
                    return tag;
                else if(A[i] == tag)
                //next positive
                    tag ++;
                else
                    ;
            }
            //i==n, miss the tag
            return tag;
        }
    };

    解法二:O(n) time and O(n) space

    稍作思考就可以知道,n容量的数组,最多覆盖的正整数为连续的1~n

    也就是说,丢失的正整数要么出现在1~n中,要么就是n+1

    因此可以构造大小为n的数组v,v[i]记录i+1这个数字是否出现在A中。

    如果tag全true则返回n+1,否则返回第一个tag为负的下标+1

    class Solution {
    public:
        int firstMissingPositive(int A[], int n) {
            if(n == 0)
                return 1;
            //tag[i] means whether i+1 exists in A
            //at most 1~n, then return n+1
            vector<bool> tag(n, false);
            for(int i = 0; i < n; i ++)
            {
                if(A[i] > 0 && A[i] <= n)
                    tag[A[i]-1] = true;
            }
            for(int i = 0; i < n; i ++)
            {
                if(tag[i] == false)
                    return i+1;
            }
            return n+1;
        }
    };

    解法三:O(n) time and O(1) space

    解法二中我们构建了新的数组tag来记录每个正整数是否出现在A中,

    其实可以省略tag数组,直接在A中记录。这点借鉴了yuyibestman想法。

    具体做法为,先将A划分为正整数与非负数。这点类似快排的partition。

    A[i]的正负号记录i+1这个数字是否出现在A中。

    由于只是符号取负,其值可以通过绝对值函数恢复。这样就代替了解法二中的tag数组了。

    class Solution {
    public:
        int firstMissingPositive(int A[], int n) {
            if(n == 0)
                return 1;
            //if A[i] is negative, i+1 exists in original A
            
            //partition, non-negative only
            int low = 0;
            int high = n-1;
            int end = n-1;
            while(low <= high)
            {
                while(low <= high && A[low] > 0)
                    low ++;
                //to here, 
                //case low > high: partition finished, high point to the end of the new array
                if(low > high)
                {    
                    end = high;
                    break;
                }
                //case A[low]<=0: low point to the first non-positive element
                
                
                while(high >= low && A[high] <= 0)
                    high --;
                //to here, 
                //case high < low: partition finished, high point to the end of the new array
                if(low > high)
                {
                    end = high;
                    break;
                }
                //case A[high]>0: high point to the first positive element
                swap(A[low],A[high]);
            }
            
            for(int i = 0; i <= end; i ++)
            {
                //check whether num is in A, and set A[num-1] to be negative
                int num = abs(A[i]);
                if(num <= end+1)
                {
                    if(A[num-1] > 0)
                        A[num-1] *= -1;
                }
                //out of range 1~end+1
            }
            
            for(int i = 0; i <= end; i ++)
            {
                if(A[i] > 0)
                    return i+1;
            }
            return end+2;
        }
    };

  • 相关阅读:
    matlab程序性能优化与混合编程技术介绍
    最大熵原理/最大熵原则/最大熵模型(the maximum entropy principle,MEP)
    马氏距离 Mahalanobis Distance
    时间序列分析
    Windows XP + Apache 2.2.4 + PHP 5.2.0 + MySQL 5.0.27 + Zend Optimizer 3.2.0环境配置方法
    栈应用——表达式求值
    Android实现模拟时钟(简单+漂亮)时针、分针、秒针
    基于循环链表的约瑟夫问题
    assert()详解
    Hadoop HPROF 的使用
  • 原文地址:https://www.cnblogs.com/ganganloveu/p/4164834.html
Copyright © 2020-2023  润新知