算法的时间复杂度和空间复杂度-例题

一、消失的数字

. - 力扣(LeetCode)

本题要求的时间复杂度是O(n) ,所以我们不能用循环嵌套;

解法一: 

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

先把0到n的数字加起来,再把原数组里面的所有元素加起来,再用前者减去后者,得出的就是消失的数字;

解法二:

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

 相同数字互相异或得到0,0和一个非零数字异或得到这个非零数字;先把原本没有消失的有序数列互相异或一遍,再和这个消失了一个数字的数组里面的数据异或一遍,因为相同的数字异或之后为0,没有消失的数据一定是成对出现的,那么最终的结果就是有序数列里面单独剩下的数据,就是消失的数字。


二、轮转数组

. - 力扣(LeetCode)

 解法一:

void rotate(int* nums, int numsSize, int k) {
    int time=k%numsSize;
    for(int i=0;i<time;i++)
    {
        int right=nums[numsSize-1];
        for(int j=numsSize-2;j>=0;j--)
        {
            nums[j+1]=nums[j];
        }
        nums[0]=right;
    } 
}

这个解法的时间复杂度是O(n^2);假设数组中的元素个数是n,time最坏是n-1,最好是0,嵌套在里面的循环是n-1次,所以是O(n^2);

每次先保留数组的最后一个数据,再把除了这个数据的前面的数据整体向后移动一格,最后再把下标为0的数据赋值为保留的那个最后的数据;

这种方法可行,但是再LeetCode上面无法通过,超出时间限制;

解法二:

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

分段逆置,再整体逆置;

解法三:

void _rotate(int* nums,int numsSize,int k, int* tmp)
{
	k%=numsSize;
    int n=numsSize;
    memcpy(tmp,nums+n-k,sizeof(int)*k);
    memcpy(tmp+k,nums,sizeof(int)*(n-k));
    memcpy(nums,tmp,sizeof(int)*n);
}
void rotate(int* nums, int numsSize, int k) {
   int* tmp=(int*)malloc(sizeof(int)*numsSize);
   _rotate(nums,numsSize,k,tmp);
}

重新开辟一个数组,使用memcpy内存操作函数去把逆置的数据从nums里面copy到tmp里面,最终再把tmp里面的所有数据copy到nums里面,最终的不能直接写nums=tmp,要用内存操作函数,这样才能让nums在内存上发生改变。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值