Java数组循环移动:最小元素前置且原数组不变的实现问询
问题分析
你遇到的核心问题有三个:
- 返回值类型不匹配:测试代码要求方法返回
int[],但你写的是void方法,无法赋值给变量b - 原数组被修改:你的代码直接操作传入的数组,导致原数组
a的内容改变,不符合测试示例中原数组保持不变的要求 - 循环移动逻辑错误:你实现的是将最小元素单独移到首位、前面元素后移,但测试示例要求的是循环左移整个数组,使最小元素到首位后,后续元素保持原循环顺序
解决方案
根据测试示例的预期,我们需要实现一个返回int[]的方法(如果作业要求确实是void,那要么测试示例有误,要么作业要求是修改传入数组,此时原数组必然会被修改)。以下分两种场景给出解决方案:
场景1:符合测试示例要求(原数组不变,返回处理后的新数组)
虽然你提到禁止创建新数组,但测试示例明确需要新数组b,这里的“禁止创建新数组”可能是指禁止创建临时辅助数组(而非结果数组)。实现步骤:
- 遍历原数组,找到最小元素的索引
minIndex - 创建一个与原数组长度相同的新数组
- 通过模运算直接映射原数组元素到新数组的对应位置,实现循环左移效果
public static int[] premakni(int[] tabela) { if (tabela == null || tabela.length == 0) { return tabela; } // 找到最小元素的索引 int minIndex = 0; for (int i = 1; i < tabela.length; i++) { if (tabela[i] < tabela[minIndex]) { minIndex = i; } } int[] result = new int[tabela.length]; // 循环左移minIndex次,直接映射元素 for (int i = 0; i < tabela.length; i++) { result[i] = tabela[(minIndex + i) % tabela.length]; } return result; }
这个方法不会修改原数组,返回的新数组完全符合测试示例的预期结果。
场景2:符合作业要求(void方法,不创建新数组,修改传入数组)
如果作业确实要求void方法且禁止创建任何新数组,那么只能修改传入的数组(此时原数组a会被修改,测试示例中原数组不变的预期不成立)。我们可以用三次反转法实现循环左移,不需要创建新数组:
public static void premakni(int[] tabela) { if (tabela == null || tabela.length <= 1) { return; } // 找到最小元素的索引 int minIndex = 0; for (int i = 1; i < tabela.length; i++) { if (tabela[i] < tabela[minIndex]) { minIndex = i; } } // 三次反转实现循环左移minIndex次 reverse(tabela, 0, minIndex - 1); reverse(tabela, minIndex, tabela.length - 1); reverse(tabela, 0, tabela.length - 1); } // 辅助反转方法,反转数组中[start, end]区间的元素 private static void reverse(int[] arr, int start, int end) { while (start < end) { int temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; start++; end--; } }
这个方法会直接修改传入的数组,执行后原数组会变成测试示例中b的预期结果。
关键说明
- 测试示例的预期明确要求原数组不变,因此场景1是更符合测试要求的方案
- 如果作业强制要求
void方法,那么只能选择场景2,但此时原数组会被修改,需要和测试代码的预期对齐
内容的提问来源于stack exchange,提问作者Red Smurf
相关产品推荐
相关产品推荐

