
本文详解 leetcode「shuffle the array」题目的核心逻辑,指出原解中数组越界(arrayindexoutofboundsexception)的根本原因,并提供简洁高效的双指针式单循环解法,附带代码实现与关键注意事项。
本文详解 leetcode「shuffle the array」题目的核心逻辑,指出原解中数组越界(arrayindexoutofboundsexception)的根本原因,并提供简洁高效的双指针式单循环解法,附带代码实现与关键注意事项。
在「Shuffle the Array」问题中,输入数组 nums 长度为 2n,结构为 [x₁, x₂, ..., xₙ, y₁, y₂, ..., yₙ],目标是将其重排为 [x₁, y₁, x₂, y₂, ..., xₙ, yₙ]。看似简单的交错合并,却极易因索引计算失误引发运行时异常——正如提问者遇到的 java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3。
问题根源在于原始代码中的三处关键错误:
-
System.arraycopy源起始索引错误:System.arraycopy(nums, n + 1, second, 0, n - 1);
此处应从索引
n开始复制后半段(即y₁起始位置),而非n + 1,导致漏掉第一个y元素,且长度传入n - 1使second数组末尾缺失一元素。 主循环范围过大:
for(int i = 0; i 中 <code>nums.length == 2n,但first和second长度仅为n,当i ≥ n时,first[i]必然越界。结果数组写入逻辑错位:
每次循环试图写入ans[i]和ans[i + 1],但未控制总写入次数,导致重复覆盖或越界(例如n=3时,i=5会尝试访问ans[5]和ans[6],而ans长度仅6,最大合法索引为5)。
✅ 正确解法应摒弃冗余分拆,采用数学映射+单次遍历:
对每个 i ∈ [0, n),直接将 xᵢ = nums[i] 放入结果数组偶数位 ans[2*i],将 yᵢ = nums[n+i] 放入奇数位 ans[2*i + 1]。该方案时间复杂度 O(n),空间复杂度 O(1)(不计输出数组),简洁且无越界风险。
public int[] shuffle(int[] nums, int n) {
int[] ans = new int[2 * n];
for (int i = 0; i <p>? <strong>关键提醒</strong>: </p>
- 切勿用
nums.length作为遍历上界,应以n(即半长)为准; - 分拆数组虽直观,但增加内存开销与索引管理复杂度,非必要不推荐;
- 所有索引运算需严格验证边界:
2*i+1 ≤ 2*n-1⇔i ≤ n-1,故循环条件i 完全安全。
此解法体现了算法设计中“用计算代替存储”的思想,是处理规律性数组重组问题的经典范式。










