时间复杂度OJ(旋转数组、消失的数字)

旋转数组

. - 力扣(LeetCode)

思路1: 每旋转一次将最后一位数保存,前N-1个数整体往后挪动一位在把保存好的最后一位数赋值到第一位,真实的旋转次数是 K %= N;K %= N 最好的情况是等于0(相当于不旋转)最坏的情况是等于N-1,时间复杂度按最坏情况算,时间复杂度为O(N^2)。

k %= numsSize;
while(k--)
{
    int tmp = nums[numsSize-1];
    for(int i = numsSize-2 ; i >= 0; i--)
    {
        nums[i+1] = nums[i];
    }
    nums[0] = tmp;
}

 需要注意的是:时间复杂度的原因这个方法过不了。

 思路2:前N-K个逆置,后K个逆置,整体逆置,时间复杂度为O(N)。

void reverse(int* nums,int left,int right)  //逆置
{
    while(left<right)                       //双指针指向首尾向中间走 相等即逆置完成
    {
        int tmp = nums[left];
        nums[left] = nums[right];
        nums[right] = tmp;
        ++left;
        --right;
    }
}
void rotate(int* nums, int numsSize, int k) 
{
    k %= numsSize;                         //先用旋转次数%数组长度取余到真实旋转次数
    reverse(nums,0,numsSize-k-1);          //将前n-k个逆置 
    reverse(nums,numsSize-k,numsSize-1);   //将后k个逆置
    reverse(nums,0,numsSize-1);            //整体逆置
}

 通过拷贝函数实现相同方法需要空间换时间

消失的数字

. - 力扣(LeetCode)

思路1:因为数组是升序,可以先排序,再依次查找,如果下一个值不等于前一个+1,下一个值就是消失数字。 

需要注意的是:因为题目要求时间复杂度为O(N),冒泡排序时间复杂度为O(N^2)、qsort快排时间复杂度为O(N*LogN),所以使用这个思路是不合适的。

等差数列

思路2:求和0到N,在依次减去数组中值,剩下的那个值就是消失数字。

             求和可以用循环直接加,也可以用等差数列公式直接算,时间复杂度为O(N)满足               题意。

实现代码:

int N = numsSize;
int ret = (N+1)*(0+N)/2; //等差数列求和:项数 *(首项+尾项)/ 2;因为numsSize是消失数字的数组长度    
                         //所以项数需要+1;
for(int i = 0 ; i < numsSize ; i++)
{
    ret-=nums[i];
    return ret;
}

需要注意的是:N太大存在溢出风险。

思路3:异或(相同的值异或==0)

实现代码: 

//创建一个变量保存异或的值
int x = 0;
//通过for循环把消失数字的数组异或一遍
for(int i = 0 ; i < numsSize ; i++)
{
    x ^= nums[i];
}
//在用消失数字数组所有值异或的数字异或一遍完整数组即可得出消失的数字;
for(int j = 0 ; j <= numsSize ; j++)
{
    x ^= nums[j];
}
//将消失的数字返回
return x;
  • 28
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值