《力扣刷题》 轮转数组

题目描述

若存在一个数组,将数组中的元素向右轮转 k 个位置(其中 k 是非负数)

关于轮转的概念如下我举一个例子

        如存在数组 nums = [1, 2, 3, 4],我们向右轮转 1 个单位,则轮转后的数组为 [4, 1,2,3]

C 语言具体代码实现

这道题我刚开始是没有思路的,于是借鉴了官方的方法:使用额外的数组!!!

        简单来讲,对于在原数组中位于索引 0 的元素,当我们向右轮转 k 个单位,那么这个元素应该被保存在额外数组索引为 0+k 位置;但是这样并不完善,对于原数组比较靠后的元素,如 nums = [1, 2, 3, 4] 中,我们向右轮转 1 个单位,对于 4 这个元素,原索引为 3,那么其新的索引应该为 (3+1 )/nums.length = 0

#include <stdio.h> 

void rotate(int *nums, int numsSize, int k){
    int newarr[numsSize];  // 使用额外的数组
    for(int i = 0; i < numsSize; i++){
        newarr[(i+k)%numsSize] = nums[i];
    }
    for(int i = 0; i < numsSize; i++){
        nums[i] = newarr[i];
    }
}

int main(void){
	int nums[] = {1, 2, 3, 4, 5, 6};
	rotate(nums, 6, 3);  // 向右轮转三个单位 
	
	// 格式化输出
	printf("[");
	for(int i = 0; i < 6; i++){
		if(i != 5){
			printf("%d,", nums[i]);
		}else{
			printf("%d", nums[i]);
		}
	}
	printf("]");
	// [4,5,6,1,2,3]
	return 0;
}

然后谈另一种方法:翻转数组!!! 

        该方法(数组的翻转)基于如下的事实:当我们将数组的元素向右移动 k 次后,尾部 k %n 个元素会移动至数组头部,其余元素向后移动 k %n 个位置

        要实现题目中的轮转数组,我们得翻转数组多次,即先将所有元素翻转,那么尾部的 k %n 个元素就被移至数组头部,然后再翻转区间 [0, k%n-1] and [k%n, n-1]

        我们以 n=5,k=2 为例进行如下展示:

操作结果
原始数组1 2 3 4 5
翻转所有元素5 4 3 2 1
翻转 [0, k%n-1] 区间的元素4 5 3 2 1
翻转 [k%n, n-1] 区间的元素4 5 1 2 3
#include <stdio.h>
 
// 交换二个元素
void swap(int *a, int *b) {
    int t = *a;
    *a = *b, *b = t;
}

// 翻转 
void reverse(int *nums, int start, int end) {
    while(start < end){
        swap(&nums[start], &nums[end]);
        start += 1;
        end -= 1;
    }
}

// 轮转 
void rotate(int *nums, int numsSize, int k) {
    k %= numsSize;  // 取余
    reverse(nums, 0, numsSize - 1);
    reverse(nums, 0, k - 1);
    reverse(nums, k, numsSize - 1);
}

int main(void){
	int nums[] = {1, 2, 3, 4, 5, 6};
	rotate(nums, 6, 3);  // 向右轮转三个单位 
	
	// 格式化输出
	printf("[");
	for(int i = 0; i < 6; i++){
		if(i != 5){
			printf("%d,", nums[i]);
		}else{
			printf("%d", nums[i]);
		}
	}
	printf("]");
	// [4,5,6,1,2,3]
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是我来晚了!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值