一、题目描述与要求
189. 轮转数组 - 力扣(LeetCode)
题目描述
给定一个整数数组 nums
,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
示例
示例1:
输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]
示例2:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
提示
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
二、解题思路
总的思路:
对题目进行分析可知,我们需要根据轮转量k,将数组后面的k个元素按照原来的顺序放到前面去,而原本前面的元素则按顺序往后移动。例如k=1,数组元素为1234567,那么轮转后的结果应改为5671234。
要实现这一过程,首先最简单的就是直接利用另一个数组,将原本数组里面的元素按照轮转后的顺序存放到辅助数组里面,然后再将辅助数组的值赋值给数组即可。其中元素轮转后所对应的位置可以由(i+k)%numsSize得到。这一方法的时间复杂度为O(n),空间复杂度也为O(n)。有没有办法能够减少所利用的空间复杂度呢?因为当数组元素过大时,就需要很大的辅助空间。
我们观察1234 567和567 1234,可以发现轮转相当于根据k的值把数组后面k个元素放到前面,因此我们也可以直接把这个数组分成两部分,分成两部分后怎么让它按照对应的顺序呢,很显然先分成两部分是很难实现排成对应的顺序。那我们想,后面k个元素是要放到前面的,而前面的元素要放到后面去,那我们不如直接先将数组进行翻转,也就是变成“逆序”。然后再把数组分成两部分,此时每一部分所包含的元素是正确的,只是顺序不正确,因为我们对其进行了一次翻转排序,因而只需要分别对两部分再次进行翻转即可。
具体步骤:
利用辅助数组:
①定义辅助数组
②按目标为辅助数组赋值
③利用辅助数组更新原有数组
数组翻转:【在原数组上进行改动】
①判断轮转量是否大于数组元素,若大于则要取余数(因为没那么多位进行轮转)
②对整个数组进行翻转(利用双指针实现首尾元素交换)
③对翻转后的数组的前k个元素进行翻转文章来源:https://www.toymoban.com/news/detail-526929.html
④对翻转后的数组的后半部分进行翻转文章来源地址https://www.toymoban.com/news/detail-526929.html
三、具体代码【C语言】
① 利用辅助数组 【时间O(n) 空间O(n)】
void rotate(int* nums, int numsSize, int k){
if( k ==0 || numsSize == 1) return;
int tem[numsSize];//定义辅助数组
for(int i=0;i<numsSize;i++){
tem[(i+k)%numsSize]=nums[i];//在辅助数组中将每一个元素放到对应位置
}
for(int i=0;i<numsSize;i++){//复制数组
nums[i]=tem[i];
}
}
②数组翻转:【在原数组上进行改动】 【时间O(n) 空间O(1)】
void swap(int* a, int* b) //传址
{
int t = *a;
*a = *b;
*b = t;
}
void reverse(int* nums, int left, int right) //对数组进行翻转
{
while (left < right)
{
swap(&nums[left], &nums[right]);//将首尾两个数进行交换
left += 1;
right -= 1;
}
}
void rotate(int* nums, int numsSize, int k){
k%=numsSize; //避免出现轮转量大于数组元素的情况
if( k ==0 || numsSize == 1) return;
//翻转整个数组
reverse(nums, 0, numsSize - 1);
//将翻转后的前面部分变回原始顺序
reverse(nums, 0, k - 1);
//将翻转后的后面部分变回原始顺序
reverse(nums, k, numsSize - 1);
}
到了这里,关于leetcode每日一题——189.轮转数组(面试经典150题)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!