力扣189.轮转数组(c语言)

题目概述

 

题目示例

题目解读

这虽然是一道算法题,但是明面没有对时空复杂度提出要求,给我们的操作空间就比较大(菜鸡狂喜,嘿嘿),这样就有两个简单的解法;

解法一:构建两层循环,直接在nums数组中移动数据。

解法二:申请堆区空间,然后从第k个元素开始拷贝,再将剩余的元素顺序拷贝,最后再将堆区数据拷贝到nums数组。

但tnnd,解法一很容易就运行超时(因为有一些极其恶心的测试数据,会使时间效率达到O(n^2),解法二的话没啥问题,但是作为当代模范青年,我们要挑战自己的软肋!!!

                              

解法三:三次逆置,只要我逆置的够快,题目就反应不过来,不多bb,直接开搞。。。

全局代码:


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

​

 以示例一为例:

 (1)首先,先对轮转次数k做处理,因为有可能 k>numSize,这样就会有规律的循环,例如,如果k>numSize,轮转1次和轮转numSize+1次的结果相同,轮转numSize次与原数组相同。酱紫,就会减少不必要的操作。

(2)第一个for循环,逆置第k个数之前的数值

 

 (3)第二个for循环,逆置后k个数值

 (4)第三个for循环,整体逆置

 这样就达到了题目要求,且时间复杂度仅为O(n);

三步的操作不能毫不相干,只能说一毛一样,所以完全可以去写一个函数,直接利用接口去操作,可以减少代码冗余,提高可阅读性。

void reserve(int* nums,int m,int n)
{
    int i=m,j=n,tmp;
    for(;i<j;i++,j--)
    {
        tmp=nums[i];
        nums[i]=nums[j];
        nums[j]=tmp;
    }
}
void rotate(int* nums, int numsSize, int k)
{
    k%=numsSize;
    reserve(nums,0,numsSize-k-1);
    reserve(nums,numsSize-k,numsSize-1);
    reserve(nums,0,numsSize-1);
}

实不相瞒

我第一次看到这个解法时,表情是酱紫的   (0.0)

                                  

 

所以说,刷算法题,要有一个高的效率,多去学习和总结解题方法和思路,死磕一个题,可以但没有必要!!!

寄了,再见。。。

                           

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

极客1号

感谢老板,老板大气!!!

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

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

打赏作者

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

抵扣说明:

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

余额充值