旋转数组
旋转数组
【描述】
给定一个数组,将数组向右移动k步,其中k为非负数。
【样例】
【挑战】
给出尽可能多的解决办法, 至少有三种方法可以解决这个问题.
能够用O(1)的时间复杂度解决问题吗?
【方法一】
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
vector<int> rotate(vector<int> &nums, int k) {
int index = nums.size() - 1;
// 整体共移动 k 步
for (int steps = 1; steps <= k; steps++) {
// 整体移动 1 步
int temp = nums[index];
for (int i = index; i > 0; i--) {
nums[i] = nums[i - 1];
}
nums[0] = temp;
}
return nums;
}
void inputElement(vector<int> &nums, int n) {
printf("输入内容:");
for (int i = 0; i < n; i++) {
int temp = 0;
scanf("%d", &temp);
nums.push_back(temp);
}
printf("\n");
}
void printElement(vector<int> nums) {
int size = nums.size();
printf("输出内容:");
for (int i = 0; i < size; i++) {
printf("%d ", nums[i]);
}
printf("\n");
}
int main() {
vector<int> nums;
int n;
int k;
printf("请输入测试数组元素个数和移动步数:");
while (scanf("%d%d", &n, &k) != EOF) {
inputElement(nums, n);
printf("初始状态:\n");
printElement(nums);
// 旋转数组
rotate(nums, k);
printf("旋转后状态:\n");
printElement(nums);
// 清空原数组,开始新一次测试
nums.clear();
printf("\n请输入测试数组元素个数和移动步数:");
}
return 0;
}
【方法二】
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
vector<int> rotate(vector<int> &nums, int k) {
// 用来存放 旋转结果
vector<int> temp;
// 考虑到 移动步数 k 会超过 数组元素总个数,因此 k = k % size
// index 0 1 2 3 4 5 6
// k 7 6 5 4 3 2 1
// size 7 7 7 7 7 7 7
// size = index + k
int size = nums.size();
int index = size - k % size;
int index = size - k % size;
// 下标 0 1 2 3 4 5 6
// 数值 1 2 3 4 5 6 7
// 旋转 5 6 7 1 2 3 4 移动 3 步后的结果
// 原数组从右往左数, 将下标为 size - k 到 size - 1 的元素,开始依次复制到 temp。
for (int i = index1; i < size; i++) {
temp.push_back(nums[i]);
}
// 原数组从左往右数,将下标为 0 到 size - k - 1 的元素,开始依次复制 temp。
for (int i = 0; i < index; i++) {
temp.push_back(nums[i])
}
// 可以用该语句 替换 前面两个 for 循环
// for (int i = 0; i < nums.size(); i++) { temp[(i + k) % size] = nums[i]; }
nums = temp;
return nums;
}
void inputElement(vector<int> &nums, int n) {
printf("输入内容:");
for (int i = 0; i < n; i++) {
int temp = 0;
scanf("%d", &temp);
nums.push_back(temp);
}
printf("\n");
}
void printElement(vector<int> nums) {
int size = nums.size();
printf("输出内容:");
for (int i = 0; i < size; i++) {
printf("%d ", nums[i]);
}
printf("\n");
}
int main() {
vector<int> nums;
int n = 0;
int k = 0;
printf("请输入测试数组元素个数和移动步数:");
while (scanf("%d%d", &n, &k) != EOF) {
inputElement(nums, n);
printf("初始状态:\n");
printElement(nums);
// 旋转数组
rotate(nums, k);
printf("旋转后状态:\n");
printElement(nums);
// 清空原数组,开始新一轮测试
nums.clear();
printf("\n请输入测试数组元素个数和移动步数:");
}
return 0;
}
【方法三】
//考虑到存在情况为 移动步数 k > 元素个数 size ,则 k = k % size
//下标 步数 个数 三者之间的关系 —— index + k % size = size, (index + k) % size = index.
// 构造哈希函数 (index + k)% size = index
// 下标 0 1 2 3 4 5 6
// 数值 1 2 3 4 5 6 7
// 旋转 5 6 7 1 2 3 4
// 下标 4 5 6 0 1 2 3
// 步数 3 3 3 3 3 3 3
// 取模 0 1 2 3 4 5 6
// temp[(index + k) % size] = nums[index];
【结果】
请输入测试数组元素个数和移动步数:7 3
输入内容:1 2 3 4 5 6 7
初始状态:
输出内容:1 2 3 4 5 6 7
旋转后状态:
输出内容:5 6 7 1 2 3 4
请输入测试数组元素个数和移动步数:4 2
输入内容:-1 -100 3 99
初始状态:
输出内容:-1 -100 3 99
旋转后状态:
输出内容:3 99 -1 -100
请输入测试数组元素个数和移动步数: