zoukankan      html  css  js  c++  java
  • [LeetCode] 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(1)的空间,可以之间开一个O(n)的数组,全部标记为0,然后A中出现过的标记为1,即可解决此问题。

    但是此题要求O(1)的空间,我们用A[i]保存i+1,这样最好做一次判断A[i] 不是i+1的内容即可达到目的。

    虽然不能再另外开辟非常数级的额外空间,但是可以在输入数组上就地进行swap操作。

     1 class Solution {
     2  public:
     3   int firstMissingPositive(int A[], int n) {
     4     for(int i = 0 ; i < n; ) {
     5       if((A[i] > 0) && (A[i] <= n) && (A[A[i]-1] != A[i])) {
     6         int t = A[A[i]-1];
     7         A[A[i]-1] = A[i];
     8         A[i] = t;
     9       } else i++;
    10     }
    11     for(int i = 0 ; i < n; i++) {
    12       if(A[i] != i+1) return i+1;
    13     }
    14     return n+1;
    15   }
    16 };

    下图以题目中给出的第二个例子为例,讲解操作过程。

    首先思路上,其次临界条件,这题和下面题异曲同工:

    n个元素的数组,里面的数都是0~n-1范围内的,求数组中重复的某一个元素,没有返回-1, 要求时间性能O(n) 空间性能O(1)。

     1 bool IsDuplicateNumber(int *array, int n)
     2 {    
     3     if(array==NULL) return false;    
     4     int i,temp;
     5     for(i=0;i<n;i++)        
     6     {    
     7         while(array[i]!=i)            
     8         {        
     9             if(array[array[i]]==array[i]) 
    10                 return true;    
    11             temp=array[array[i]];    
    12             array[array[i]]=array[i];        
    13             array[i]=temp;            
    14         }        
    15     }    
    16     return false;    
    17 }

    把每个数放到自己对应序号的位置上,如果其他位置上有和自己对应序号相同的数,那么即为有重复的数值。

    当没有重复数值出现时,可以看做一种特殊的排序。

    看到“里面的数都属于范围[0,n-1]”会不会条件反射想到计数排序? 可惜题目要求O(1)空间,而且仔细看题就知道与计数排序八竿子打不着。不过计数排序里面蕴含的思想我们还是可以使用的。

        回忆一下计数排序的算法,如果待排序的值大小范围在[0,n-1]之内,我们完全可以构造一个数组B[n],将待排序数组中,值为x(0<=x<=n-1)的元素放到B[x]中去,这里暂时先不说重复的情况。说白了就是如果有元素的值范围都在一个固定区间内的情况,那么我们完全可以把元素的值与数组下标映射起来。那么这道题也一样。

        下面给出一位网友的做法,就原数组的值和下标进行交换,然后新值是个标记。o(n)内可以找到相同标记就返回。只要1个中间变量。当然这个做法可不一定正确,也不一定是最优的。大家仁者见仁智者见智哈。

  • 相关阅读:
    redis命令参考(四) set集合
    redis命令参考(三) List列表相关
    redis命令参考(二)
    redis命令参考(一) SortedSet相关
    insert_into_on_dumplicate_key
    laravel深入分析
    开发中GBK+UTF8编码的处理
    ajax封装调用
    linux正则表达式的用法
    linux 如何保证使程序后台运行(nohup &)
  • 原文地址:https://www.cnblogs.com/diegodu/p/3788280.html
Copyright © 2011-2022 走看看