旋转数组

旋转数组

【描述】
给定一个数组,将数组向右移动k步,其中k为非负数。

【样例】
image

【挑战】
给出尽可能多的解决办法, 至少有三种方法可以解决这个问题.
能够用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

请输入测试数组元素个数和移动步数:
posted @ 2022-02-16 22:17  hellozwx  阅读(52)  评论(0编辑  收藏  举报