轮转数组(c语言实现)三种方法

一.题目描述

在这里插入图片描述

二.题目分析

k只说是非负数,没说具体范围,万一所旋转次数大于nums数组内容时就得另当别论
解决办法:k=k%numsSize

三.题目解决


1.旋转一次:下标为numsSize-1的数值单独放在一个tmp变量中,后面数据依次往前挪动数据,之后再把tmp放在最前面,就完成了一次数据旋转,一共旋转k此就可以

代码如下

void rotate(int* nums, int numsSize, int k)
{
    if(k>=numsSize)
    {
        k=k%numsSize;
    }
    int i=0;
    //k次旋转
    while(k--)
    {
    //下标为numsSize-1的数值单独放在一个tmp变量中
        int tmp=nums[numsSize-1];
        //面数据依次往前挪动数据
        for(i=numsSize-2;i>=0;i--)
        {
             nums[i+1]=nums[i];
        }
        //tmp放在最前面
         nums[0]=tmp;   
    }

}

分析可得:时间复杂度为O(n^2),空间复杂度为O(1)

可不可以优化时间复杂度呢?

2.开辟一个新空间,先将后k个拷贝过来,再将剩下的数据拷贝过来,最后把数据拷贝会原数组中


这里就有就两种开辟空间的方法;
a.开辟数组
b.动态开辟

a.代码实现

void rotate(int* nums, int numsSize, int k)
{
    //开辟空间,leetcode支持变长数组
    int arr[numsSize];
    if(k>=numsSize)
    {
        k=k%numsSize;
    }
    int i=0;
    //数据拷贝新空间中
    for(i=0;i<k;i++)
    {
        arr[i]=nums[numsSize-k+i];
    }
    int j=0;
    for(j=0;j<numsSize-k;j++)
    {
        arr[i]=nums[j];
        i++;
    }
    //新空间数据拷贝会nums数组
    for(int ch=0;ch<numsSize;ch++)
    {
        nums[ch]=arr[ch];
    } 
}

b.代码实现

在这里插入代码片void rotate(int* nums, int numsSize, int k)
{
    //动态开辟
    int*arr=(int*)malloc(sizeof(int)*numsSize);
    if(arr==NULL)
    {
        perror("malloc fail");
        exit(-1);
    }
    //数据拷贝新空间中
    if(k>=numsSize)
    {
        k=k%numsSize;
    }
    int i=0;
    for(i=0;i<k;i++)
    {
        arr[i]=nums[numsSize-k+i];
    }
    int j=0;
    for(j=0;j<numsSize-k;j++)
    {
        arr[i++]=nums[j];
    }
    //新空间数据拷贝会nums数组
    for(int ch=0;ch<numsSize;ch++)
    {
        nums[ch]=arr[ch];
    }
    //释放空间
    free(arr);
    arr=NULL;
}

动态开辟不要忘记用完了释放空间

空间复杂度为O(n),时间复杂度O(n)

可不可以继续优化呢?

3. 先将前numsSize-k个数据逆置,后将后k个数据逆置,最后把整个数组逆置

代码实现

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)
{
    if(k>=numsSize)
    {
        k=k%numsSize;
    }
    //numsSize-k个数据逆置
    reverse(nums,0,numsSize-k-1);
    //将后k个数据逆置
    reverse(nums,numsSize-k,numsSize-1);
    //整个数组逆置
    reverse(nums,0,numsSize-1);
}

以上代码仅供参考 如有错误请大家指点 我会尽快去改正 欢迎大家来评论~~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lim 鹏哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值