C语言——轮转数组

一、题目简述

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。例如:
输入:nums=[1,3,5,6,4,1,2,5] ,numsSize=8
k=3
输出:nums=[1,2,5,1,3,5,6,4]

二、方法分析

方法一:
将nums最后一个元素取出,tmp=nums[numSize]
将数组nums向后移动一位,nums[j+1]=nums[j]
将tmp给nums第一个元素,nums[0]=tmp
重复上述过程k次,while(k–)
时间复杂度:O(n^2)

方法二:
将nums数组最后k个元素逆置,numSize-k到numSize-1
将nums数组前numSize-k个数逆置,0到numSize-k-1
再将整个数组逆置即可,0到numSize-1
例如:
nums=[1,3,5,6,4,1,2,5] ,numsSize=8
k=3
逆置最后3个元素:
nums=[1,3,5,6,4,5,2,1]
逆置前五个元素:
nums=[4,6,5,3,1,5,2,1]
逆置整个数组:
nums=[1,2,5,1,3,5,6,4]

本题采用第二种方法更为简便,只需一个逆置函数即可

三、代码分析

1、处理k的范围
	k%=numsSize;//将取余

如果将数组向右轮转numSize(数组长度)次,那么nums还是保持原样;所以如果向右轮转 n*numSize+m次,那么相当于向右轮转m次。0<=m<=numSize-1,n为正整数。
所以对k%=numSize,保证0<=k<=numSize-1,也防止数组的越界

2、逆置函数
void reverse(int* nums,int left,int right)
{
    while(left<right)
    {
        int tmp=nums[left];
        nums[left]=nums[right];
        nums[right]=tmp;
        left++;
        right--;
    }
}

left代表左边的位置,right代表右边位置,同时向中间移动,进行交换,即可完成数组逆置函数。

3、实现右轮转
    int left=0;
    int right=numsSize-k-1;
    reverse(nums,left,right);//逆置前numSize-k个元素

将前numSize-k个元素进行逆置,调用写好的reverse函数。

    left=numsSize-k;
    right=numsSize-1;
    reverse(nums,left,right);//逆置后k个元素

将后k个元素进行逆置,调用写好的reverse函数。

    left=0;
    right=numsSize-1;
    reverse(nums,left,right);//逆置整个数组

逆置整个数组,调用写好的reverse函数。

四、完整代码

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) {
    k%=numsSize;//保证0<=k<=numSize-1
    int tmp=0;
    int left=0;
    int right=numsSize-k-1;
    reverse(nums,left,right);//逆置前numSize-k个元素
    left=numsSize-k;
    right=numsSize-1;
    reverse(nums,left,right);逆置后k个元素
    left=0;
    right=numsSize-1;
    reverse(nums,left,right);//逆置整个数组
}
  • 24
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值