先看题目
给定一个整数数组 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.把数组最后一个数存起来
2.数组整体后移
3.把这个数放到数组第一个
上代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//暴力求解
void reverse(int nums[],int n,int k)
{
while (k--)
{
//把数组最后一个数存起来
int tmp = nums[n - 1];
//数组整体后移
int i = 0;
for (i = n - 1; i > 0; i--)
{
nums[i] = nums[i - 1];
}
//把这个数放到数组第一个
nums[0] = tmp;
}
}
int main()
{
int nums[] = { 1,2,3,4,5,6,7 };
int k = 3;
int numsSize = sizeof(nums) / sizeof(nums[0]);
reverse(nums, numsSize,k);
int i = 0;
for (i = 0; i < numsSize; i++)
{
printf("%d ", nums[i]);
}
return 0;
}
这种方法是最容易想到的方法,但是面对一些对复杂度有要求的题,这种方法是不行的。
时间复杂度:O(N^2)
空间复杂度:O(1)
解法二:空间换时间
1.新建一临时数组
2.先拷贝后k个元素
3.再拷贝前n-k个元素
4.用新建数组覆盖原数组
上代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//空间换时间
void reverse(int* nums, int n, int k)
{
//1.动态开辟临时数组
int* tmp = (int*)malloc(sizeof(int) * n);
//2.把原数组后k个,拷贝到新数组
memcpy(tmp, nums + n - k, sizeof(int) * (k));
//3.再把原数组前n-k个,拷贝到新数组
memcpy(tmp + k, nums, sizeof(int) * (n - k));
//4.用新建数组覆盖原数组
memcpy(nums, tmp, sizeof(int) * n);
free(tmp);
tmp = NULL;
}
int main()
{
int nums[] = { 1,2,3,4,5,6,7 };
int k = 3;
int numsSize = sizeof(nums) / sizeof(nums[0]);
k %= numsSize;
reverse(nums, numsSize, k);
int i = 0;
for (i = 0; i < numsSize; i++)
{
printf("%d ", nums[i]);
}
return 0;
}
时间复杂度:O(N)
空间复杂度:O(N)
解法三:三段逆置
这是可以说是找规律,也可以说使用数学思维解决问题
1.前n-k个逆置
原来:1 2 3 4 5 6 7
逆置:4 3 2 1 5 6 7
2.后k个逆置
原来:4 3 2 1 5 6 7
逆置:4 3 2 1 7 6 5
3.整体逆置
原来:4 3 2 1 7 6 5
逆置:5 6 7 1 2 3 4
上代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
reverse(int* a, int left, int right)
{
while (left < right)
{
int tmp = a[left];
a[left] = a[right];
a[right] = tmp;
++left;
--right;
}
}
int main()
{
int nums[] = { 1,2,3,4,5,6,7 };
int k = 3;
int numsSize = sizeof(nums) / sizeof(nums[0]);
k %= numsSize;
reverse(nums, 0, numsSize - k-1);
reverse(nums, numsSize - k, numsSize-1);
reverse(nums, 0, numsSize-1);
int i = 0;
for (i = 0; i < numsSize; i++)
{
printf("%d ", nums[i]);
}
return 0;
}
时间复杂度:O(N)
空间复杂度:O(1)
下标非常易错
reverse(nums, 0, numsSize - k-1);
reverse(nums, numsSize - k, numsSize-1);
reverse(nums, 0, numsSize-1);
memcpy(tmp, nums + numsSize - k, sizeof(int) * (k));
memcpy(tmp + k, nums, sizeof(int) * (numsSize - k));
memcpy(nums,tmp, sizeof(int) * numsSize);
画图来帮助理解