数组三区块划分后交换首尾区块的实现问题及优化咨询
嘿,我来帮你梳理下这个问题,顺便给你优化下实现方式!
首先明确你的需求:把数组拆成三个区块——区块1(0到pos1-1)、区块2(pos1到pos2)、区块3(pos2+1到末尾),最终把数组调整为「区块3 + 区块2 + 区块1」的顺序对吧?先聊聊你现有代码的问题,再给你更高效简洁的实现方案。
原代码的问题
你的代码逻辑方向是对的,但存在冗余的遍历操作:你先用三个循环计算三个区块的长度,再用三个循环复制元素,前后总共遍历了6次数组,完全没必要。而且这种分步计算长度的方式,不仅增加了代码量,还容易在索引计算时出错(比如循环条件写错就会导致长度计算偏差)。
更优的实现方式(创建新数组)
直接按目标顺序复制三个区块即可,不需要提前计算长度,代码更简洁可读性更高,而且只需要3次遍历:
public void switchPositions(int pos1, int pos2) { int totalLength = cards.length; int[] newCards = new int[totalLength]; int currentIndex = 0; // 先复制区块3:从pos2+1到数组末尾 for (int i = pos2 + 1; i < totalLength; i++) { newCards[currentIndex++] = cards[i]; } // 再复制区块2:从pos1到pos2(含两端) for (int i = pos1; i <= pos2; i++) { newCards[currentIndex++] = cards[i]; } // 最后复制区块1:从数组开头到pos1-1 for (int i = 0; i < pos1; i++) { newCards[currentIndex++] = cards[i]; } // 替换原数组 cards = newCards; }
用你给的示例测试:原数组[1,2,3,4,5,6,7,8,9,10,11,12],pos1=1、pos2=9时:
- 区块3是
[11,12],先复制到新数组开头; - 区块2是
[2,3,...10],接着复制; - 区块1是
[1],最后复制;
最终得到[11,12,2,3,4,5,6,7,8,9,10,1],完全符合预期。
进阶:原地交换(节省空间)
如果不想创建新数组(虽然52个元素的空间可以忽略不计),可以用数组反转的方式实现原地修改,步骤如下:
- 反转区块1(0到pos1-1);
- 反转区块3(pos2+1到末尾);
- 反转整个数组;
- 反转新数组的前
(totalLength - pos2 -1)个元素(原区块3的长度); - 反转新数组从
(totalLength - pos2 -1 + pos2 - pos1 +1)到末尾的元素(原区块1的长度);
不过这种方式代码复杂度更高,可读性差,对于扑克牌这种小规模数组,完全没必要。还是推荐上面的新数组实现,简单直观不容易出错。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

