轮转数组

题目描述:

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例:

在这里插入图片描述

题目链接:https://leetcode.cn/problems/rotate-array/

解题思路:

思路一

思路一: 每次记录下数组最后一个值,再将数组中元素从后往前向依次后移一位,再将记录下来的值放到数组的首元素位置,执行k次。

解法图示:

在这里插入图片描述
但这样写出来的代码的时间复杂度为O(N^2),在力扣上跑不过,所以参考一下就行。

思路二

思路二: 创建一个额外数组。因为我们要轮转原数组的后k个元素,所以轮转后的数组中的前k个元素就是轮转前数组中的后k个元素。所以我们就可以先将原数组中的后k个元素拷贝到新创建数组中的前k个位置处,然后再将原数组中剩余元素拷贝到新创建数组中的剩余位置,再将新创建数组中元素依次拷贝回原数组中即可。

解法图示:

在这里插入图片描述

思路三

思路三: 三次逆转法:

1.先将整个数组逆转;
2.再将nums中的子数组下标为[0—(k-1)]逆转;
3.再将nums中的剩余的子数组下标为[k—(size-1)]逆转。

解法图示:

在这里插入图片描述

示例代码

思路一:

思路一:

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

注意: 这个代码过不了(时间复杂度O(N^2)),参考一下就行了。

思路二:

思路二:

//方二:使用额外的数组
void rotate(int* nums, int numsSize, int k) {
    int arr[numsSize];
    int i=0;
    for(i=0;i<numsSize;i++)//将每个元素按要求放到新数组中
    {
        arr[(i+k)%numsSize]=nums[i];
    }
    for(i=0;i<numsSize;i++)//再将新数组中元素遍历赋值到题干数组中
    {
        nums[i]=arr[i];
    }
}

补充: 在上述代码中当k>numsSize时,其实就不用轮转k次了,只需要轮转k%numsSize就可以了,多余的都是重复轮转。

思路三:

思路三:

//逆转函数
void reverse(int* nums,int begin,int end)
{
    int tmp;
    while(begin<end)
    {
        tmp=nums[end];
        nums[end]=nums[begin];
        nums[begin]=tmp;

        begin++;
        end--;
    }
}

void rotate(int* nums, int numsSize, int k) {
    //方法三:三次逆转法
    //当k>numsSize时去除多余的重复轮转
    if(k>numsSize)
    {
        k=k%numsSize;
    }

    reverse(nums,0,numsSize-1);//全部逆转
    reverse(nums,0,k-1);//逆转下标为0---(k-1)的元素
    reverse(nums,k,numsSize-1);//逆转下标为k---(numsSize-1)的元素
}
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值