题目
从标准输入读入一个长度为 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