数据结构初阶---复杂度

//复杂度表示方法:

//训练题1:消失的数字

//数组nums包含从0~numsSize的所有整数,但其中缺了一个。请编写代码在O(N)时间内完成

//思路一:先排序,再比较

//不可行,冒泡O(N^2),qsort(快排)O(n*logn)----->都不可行

//思路二:计算0~n的所有数字和,再减去数组中的每个数据,剩下的数字就是缺了的数据

//缺陷:所有数字和太大,存在溢出风险

int missingNumber(int* nums, int numsSize){
    int n=numsSize;
    int sum=(numsSize+1)*(0+n)/2;
    for(int i=0;i<n;i++)
    {
        sum-=nums[i];
    }
    return sum;
}

//思路三:异或,相同为零,相异为一

//把数字展开成二进制的形式,每个二进制位出现了两个1就会归0,最后每一个二进制位剩下的数字1算出来就是那个只出现一次的数字。0和所有数字异或都等于那个数字

//注意两个for循环循环的次数不一样

int missingNumber(int* nums, int numsSize){
    int n=0;
    for(int i=0;i<numsSize;i++)
    {
        n^=nums[i];
    }
    for(int i=0;i<=numsSize;i++)
    {
        n^=i;
    }
    return n;
}

//训练题2:轮转数字

//思路一:使用普通的O(N^2)算法,会超时!!!

void rotate(int* nums, int numsSize, int k) {
    k%=numsSize;//注意当为7的倍数时数组不变;
    while(k--)
    {
        int tmp=nums[numsSize-1];
        for(int i=numsSize-2;i>=0;i--)
        {
            nums[i+1]=nums[i];
        }
        nums[0]=tmp;
    }
}

//思路二:

void reverse(int *a,int j,int k)
{
    int left=j;
    int right=k;
    while(left<right)
    {
        int tmp=a[left];
        a[left]=a[right];
        a[right]=tmp;
        left++;
        right--;
    }
}
void rotate(int* nums, int numsSize, int k) {
    k%=numsSize;
    reverse(nums,0,numsSize-k-1);
    reverse(nums,numsSize-k,numsSize-1);
    reverse(nums,0,numsSize-1);
}

//注意:reverse函数可以不用返回数组指针,因为传的是指针,直接就改变了原数组

//没有空间复杂度限制的时候可以新开辟一块空间,先拷贝后面逆置的那一块数据,再把前面那块数据拷贝进去

//拓展:二分查找(两种写法)

//递归时间复杂度:所有递归调用次数累加

//规律:N-(2的几次方)=进入的第几层Fib(即Fib()括号中的数字)

//错位相减法

//改进方法:把递归变循环//时间复杂度变为O(N)

//~空间复杂度

//以空间换时间,时间O(N),空间O(N)

void reverse(int *a,int n,int k)
{//从哪个点开始,拷贝几个数据
    int *tmp=(int*)malloc(sizeof(int)*n);
    memcpy(tmp,a+n-k,sizeof(int)*(k));
    memcpy(tmp+k,a,sizeof(int)*(n-k));
    memcpy(a,tmp,sizeof(int)*n);
}
void rotate(int* nums, int numsSize, int k) {
    k%=numsSize;
    reverse(nums,numsSize,k);
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值