力扣题目分享:189. 轮转数组(C语言)

题目:

暴力解法(超时):

第一个想到的应该都是暴力解法,也就是每次都将数组除了最后一个元素都整体往后移一位,然后将刚才的最后一个元素放到第一个位置

就拿题目的用例一来举例

 代码如下

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

然而这个算法的时间复杂度是O(K*N),会导致超时

解法一:翻转数组:

这里开始正式说解法,还是拿上面的示例一来说,可以以k=3为依据分成如图所示,即前n-k个后k个元素

先将前n-k个元素(也就是[0,n-k])翻转

再将后k个元素翻转 

最后将整个数组再翻转,就得到最终结果了

 代码如下

void resverse(int *nums,int left,int right)//翻转数组
{
  int tmp,i;
  while(left<right)
  {
    tmp=nums[left];
    nums[left]=nums[right];
    nums[right]=tmp;
    left++;
    right--;
  }
}
void rotate(int* nums, int numsSize, int k) 
{
    k%=numsSize;
    resverse(nums,0,numsSize-1-k);//翻转前n-k个元素
    resverse(nums,numsSize-k,numsSize-1);//翻转后k个元素
    resverse(nums,0,numsSize-1);//翻转整个数组
}

解法二:空间换时间(再开辟一个数组):

还是拿上面的示例一来举例,一样先给数组分成两个部分,我们可以再开一个和原数组大小一致的数组

 先将最后k个元素移过来

再将前n-k个元素移过来

 但最后数据是要在原数组的,所以要再把tmp中的数据复制到arr,这样就完成了

 但如果只是这样的话还有个小bug,如果k是10呢?k比数组的大小还要大该怎么办?

如果k等于原数组大小的话就相当于没动.

拿示例一来举例,如果k=7,翻转了7次,那就最后还是等于原来的数组

所以要将k%=numsSize,这样可以保证k<numsSize

代码如下

void rotate(int* nums, int numsSize, int k) 
{
    int *tmp=(int*)malloc(sizeof(int)*numsSize);//开辟一个和原数组同样大小的新数组
    k%=numsSize;//确保k<numsSize

    int i,j=0;
    for(i=numsSize-k;i<numsSize;i++)//将后k个元素移到新数组
      tmp[j++]=nums[i];
    for(i=0;i<numsSize-k;i++)//将前n-k个元素移到新数组
      tmp[j++]=nums[i];
    for(i=0;i<numsSize;i++)//将新数组的数据复制到原数组
      nums[i]=tmp[i];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值