第一个缺失的最小正数(优化)

题目中提到线性时间和常数级的空间限制。

方法1中循环中虽然出现循环,但是时间复杂度仍然是线性级别的,且空间复杂度为常数级别;

方法2中采用递归思想。虽然时间复杂度满足,但是空间复杂度随着递归深入成与数组长度线性相关;

方法3和方法1类似,只是方法3采用每次遇到小于数组长度n的正整数,就进行调换位置,方法1则用一个临时变量来存储。

方法4是通过将正数都放后面,从第一个正数开始,将存在小于n,对应位置置为负数。也是用到哈希原理。

方法1-4都是以数组本身作为哈希表。

方法5虽然空间复杂度为0,但是时间复杂度可能为O(n2),比如最坏情况数组元素为{1,2,3,4,5,5,6,.....,n};

方法1:

int firstMissingPositive(int A[], int n)
{
    int index=0,i=0,temp=0;
    while(i < n)
    {
        index=A[i]-1;
        if(A[i]>0 &&A[i]<=n &&A[i]!= A[index]){
            if((A[index] <=0 ||A[index]> n))
                A[index]=index+1;
            else  {
                do {
                    temp=A[index];
                    A[index]=index+1;
                    index=temp-1;
                } while(index+1!=A[index]&&A[index]>0&&A[index]<=n);
                if(A[index]<=0||A[index]>n)A[index]=index+1;
            }
        }
        i++;
    }
    for(i = 0; i < n; i++)
        if(A[i]!=i+1) break;
    return i+1;
}

方法2:

void move(int *nums,int index,int pNums){
    int temp=nums[index];
    if(temp>pNums||temp==nums[temp-1])return;
    nums[index]=0;
    if(nums[temp-1]>0)move(nums,temp-1,pNums);        
    nums[temp-1]=temp;   
}
int firstMissingPositive(int* nums, int numsSize) {
    int i=0,count=0;
    for(i=0;i<numsSize;i++)
        if(nums[i]>0)count++;
    for(i=0;i<numsSize;i++){
        if(nums[i]<=0||nums[i]>count)continue;
        move(nums,i,count);
    }
    for(i=0;i<count;i++)
        if(nums[i]!=i+1) break;
    return i+1;
}

方法3:

int firstMissingPositive(int A[], int n)
{
    int index=0,i=0;
    while(i < n)
    {
        if(A[i]<=0 ||A[i]>n || A[i]== A[A[i]-1]){ i++;continue; }
        index=A[i]-1;
        if(A[index] <=0 ||A[index]> n){
            A[index]=index+1;
            i++;
        }
        else
        {
            A[i] = A[index];
            A[index] = index+1;
        }
    }
    for(i = 0; i < n; i++)
        if(A[i]!=i+1) break;
    return i+1;
}

再看看别人写的

方法4:

int sagrigate(int *a,int n)
{
    int j=0;
    int temp=0;
    for(int i =0 ;i<n;i++)
    {
        if(a[i]<=0)
        {
           temp=a[j];
            a[j]=a[i];
            a[i]=temp;
            j++;
        }
    }
    return j;
}

int  miss(int *a,int n)
{
    for(int i=0;i<n;i++)
    {
        if( abs(a[i])-1<n && a[abs(a[i])-1]>0)
        {
            a[abs(a[i])-1]=-a[abs(a[i])-1];
        }
        
    }
    for(int i=0;i<n;i++)
    {
        if(a[i]>0)
            return i+1;
    }
    
     return n+1;
}

int firstMissingPositive(int* nums, int n) {
    int k;
    k= sagrigate(nums,n);
    return  miss(nums+k,n-k);
}

方法5:

int firstMissingPositive(int* nums, int numsSize) {
    int t = 1;
    int i;
    for(i = 0; i < numsSize;)
    {
        if(nums[i] > 0 && nums[i] == t)
        {
            t++;
            i = 0;
            continue;
        }
        else
            i++;
    }
    return t;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值