修复HackerEarth CodeMonk中Java数组旋转代码的数组越界异常
修复Java数组旋转代码中的ArrayIndexOutOfBoundsException错误
在HackerEarth的CodeMonk平台执行一段Java数组旋转代码时,出现执行失败,抛出java.lang.ArrayIndexOutOfBoundsException: 1异常,异常栈指向TestClass.Rotate方法第25行和TestClass.main方法第62行。以下是原代码:
import java.util.*; class TestClass { // Function to rotate array static void Rotate(int arr[], int d, int n) { // Storing rotated version of array int temp[] = new int[n]; // Keeping track of the current index // of temp[] int k = 0; // Storing the n - d elements of // array arr[] to the front of temp[] for (int i = d+1; i < n-1; i++) { temp[k] = arr[i]; k++; } // Storing the first d elements of array arr[] // into temp for (int i = 0; i < d+1; i++) { temp[k] = arr[i]; k++; } // Copying the elements of temp[] in arr[] // to get the final rotated array for (int i = 0; i < n-1; i++) { arr[i] = temp[i]; } } // Function to print elements of array static void PrintTheArray(int arr[], int n) { for (int i = 0; i < n-1; i++) { System.out.print(arr[i] + " "); } } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); int[] arr = new int[n]; // Taking input for array elements for (int i = 0; i < n-1; i++) { arr[i] = sc.nextInt(); } int N = arr.length; // Function calling Rotate(arr, k, N); // Printing the rotated array PrintTheArray(arr, N); } }
错误原因分析
- 数组输入不完整:main方法中读取数组元素的循环条件是
i < n-1,导致数组最后一个元素(索引n-1)未被赋值,始终为默认值0,后续操作可能触发索引越界或逻辑错误。 - 旋转方法循环边界错误:
- 第一个循环
i < n-1会漏掉数组最后一个元素,导致temp数组无法填满,后续复制时数据缺失。 - 第二个循环
i < d+1,若d+1超过数组长度n,会直接访问arr的越界索引,这是引发ArrayIndexOutOfBoundsException的直接原因。 - 第三个循环
i < n-1同样漏掉最后一个元素的复制,导致原数组最后一个位置未更新。
- 第一个循环
- 打印方法边界错误:
i < n-1会漏掉最后一个元素的输出。
修复步骤
- 统一修正所有循环的边界条件:将
i < n-1改为i < n,确保数组所有元素都被处理。 - 调整旋转逻辑:原代码的旋转逻辑是移动
d+1个元素,若需求是向左旋转d次,需将循环起始值改为i = d,第二个循环条件改为i < d,保证旋转次数正确。
修复后的完整代码
import java.util.*; class TestClass { // 向左旋转数组d次:将前d个元素移到末尾 static void Rotate(int arr[], int d, int n) { int temp[] = new int[n]; int k = 0; // 存储从d到n-1的元素到temp前半部分 for (int i = d; i < n; i++) { temp[k] = arr[i]; k++; } // 存储前d个元素到temp后半部分 for (int i = 0; i < d; i++) { temp[k] = arr[i]; k++; } // 将temp的所有元素复制回原数组 for (int i = 0; i < n; i++) { arr[i] = temp[i]; } } // 打印数组所有元素 static void PrintTheArray(int arr[], int n) { for (int i = 0; i < n; i++) { System.out.print(arr[i] + " "); } } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); int[] arr = new int[n]; // 读取全部n个数组元素 for (int i = 0; i < n; i++) { arr[i] = sc.nextInt(); } // 调用旋转方法 Rotate(arr, k, n); // 打印旋转后的数组 PrintTheArray(arr, n); } }
额外补充(向右旋转场景)
如果需求是向右旋转d次,可调整旋转逻辑,同时处理旋转次数超过数组长度的情况:
static void RotateRight(int arr[], int d, int n) { d = d % n; // 避免旋转次数超过数组长度 int temp[] = new int[n]; int k = 0; // 存储最后d个元素到temp前半部分 for (int i = n - d; i < n; i++) { temp[k] = arr[i]; k++; } // 存储前n-d个元素到temp后半部分 for (int i = 0; i < n - d; i++) { temp[k] = arr[i]; k++; } // 批量复制回原数组 System.arraycopy(temp, 0, arr, 0, n); }
内容的提问来源于stack exchange,提问作者Yadnyesh-Dashpute
相关产品推荐
相关产品推荐

