
本文介绍一种高效、原地操作的java数组循环移位方法:通过一次遍历定位最小值索引,再根据其位置选择左旋或右旋策略,将最小值移至首位置,同时严格保持其余元素的相对顺序,且不依赖额外数组或java工具类。
本文介绍一种高效、原地操作的java数组循环移位方法:通过一次遍历定位最小值索引,再根据其位置选择左旋或右旋策略,将最小值移至首位置,同时严格保持其余元素的相对顺序,且不依赖额外数组或java工具类。
要实现题设要求的 premakni() 方法——即将数组循环移位,使最小元素位于索引 0 处,且其余元素相对顺序不变,关键在于理解“循环移位”本质:它不是简单地把最小值“抽出来放前面”,而是将整个数组视为环形结构,以最小值所在位置为新起点进行切分与拼接。
例如,对数组 [8, 5, 6, 2, 1, -1, -100, 425, 84],最小值 -100 位于索引 6。目标结果是 [-100, 425, 84, 8, 5, 6, 2, 1, -1],这等价于从索引 6 开始,依次取元素直到末尾,再从开头取到索引 5 ——即 以索引 6 为断点,执行一次左旋(rotate left)6 步,或等价地 右旋 3 步(因 9 - 6 = 3)。为减少移动次数,应选择旋转步数更少的方向:若最小值索引为 pos,则左旋 pos 步,或右旋 length - pos 步;取二者较小者即可。
以下是符合全部约束(无新数组、无额外类、原地修改、返回新引用)的完整实现:
import java.util.Arrays;
public class ArrayRotator {
/**
* 返回一个新数组,其元素为原数组循环移位后的结果,
* 使得最小值位于索引0,且其余元素相对顺序保持不变。
* 原数组不被修改。
*/
public static int[] premakni(int[] tabela) {
if (tabela == null || tabela.length == 0) {
return tabela; // 边界处理
}
// 1. 找到最小值及其首次出现的索引
int minIndex = 0;
int minValue = tabela[0];
for (int i = 1; i <p>✅ <strong>关键说明与注意事项:</strong> </p>
- 为何不能用 void? 题目测试代码 int[] b = premakni(a); 明确要求方法返回 int[],因此 premakni 必须是返回新数组的非 void 方法。原始 void 尝试会编译失败。
- 为何不就地修改 a? 测试输出显示 a 未变(如 a={0,1,2,-1,-2} 输出仍为 0 1 2 -1 -2),而 b 是移位后的新序列,证明原数组必须保持不变,因此必须创建并返回新数组。
- 时间与空间复杂度: 时间 O(n),仅两次线性扫描(找最小值 + 复制);空间 O(n),用于存储结果数组——这是满足“不修改原数组 + 返回新序列”要求的必要开销。
- 关于“不使用额外 Java 类”: 上述实现仅使用基本数组和 % 运算符,完全符合约束;Arrays.toString() 仅用于演示,非核心逻辑。
? 进阶提示(若真需原地旋转且允许修改原数组):
可采用三次反转法(reverse three times)实现 O(1) 空间、O(n) 时间的原地循环移位(如 reverse(0, pos-1); reverse(pos, n-1); reverse(0, n-1);),但本题场景下,因测试明确需要返回新数组且保留原数组,直接按模运算构造结果是最清晰、安全且符合题意的解法。
综上,premakni() 的正确语义是:基于输入数组生成并返回一个新的循环移位数组,使最小值居首,顺序不变——理解这一点,是写出正确答案的第一步。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











