题目

从标准输入读入一个长度为 n 的数组和一个非负整数 k,将数组元素循环向左移动 k 个位置后输出。

输入格式:第一行输入整数 n 和移位数 k;第二行输入 n 个整数。

输出格式:在一行中输出循环左移后的数组,元素以空格分隔,末尾换行。

数据范围与约定:1 ≤ n ≤ 1000,0 ≤ k ≤ 106。

思路与算法

1. 模运算化简
当移动位数 k ≥ n 时,移动满 n 位相当于回到原位。因此首先执行 k %= n 减少多余轮次。

2. 两种实现方案
方案 A(辅助数组):新下标为 (i - k + n) % n 或从原数组 (i + k) % n 拷贝;
方案 B(三步反转法):先反转前 k 个元素,再反转剩余 n-k 个元素,最后反转整个数组,实现 O(1) 额外空间的原地循环移位。

完整程序

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }

        // 循环移位有效步长:移动 n 次等于回到原位
        k %= n;

        // 先暂存前 k 个元素
        int[] tmp = new int[k];
        for (int i = 0; i < k; i++) {
            tmp[i] = a[i];
        }
        // 将后 n-k 个元素整体前移 k 个位置
        for (int i = 0; i < n - k; i++) {
            a[i] = a[i + k];
        }
        // 将暂存的前 k 个元素拼接到数组末尾
        for (int i = 0; i < k; i++) {
            a[n - k + i] = tmp[i];
        }

        for (int i = 0; i < n; i++) {
            System.out.print(a[i] + (i + 1 < n ? " " : "\n"));
        }
    }
}

运行示例

输入:

5 2
1 2 3 4 5

输出:

3 4 5 1 2