如何用交换法转置二维ArrayList?求无额外集合的实现方案及代码修正
二维ArrayList转置的交换实现方案
先看你原有代码的几个核心问题:
Collections.swap(A, A.get(i).get(j), A.get(j).get(i))用法错误:Collections.swap的第一个参数是要操作的目标List,你传的外层A是存储行的List,而A.get(i).get(j)是第i行第j列的元素,不是外层List的元素索引,完全用错了对象。- 遍历范围错误:如果遍历所有i和j,会导致元素被重复交换(比如(i,j)和(j,i)交换两次,等于没换);如果是矩形矩阵(行数列数不等),还会直接出现索引越界。
方案1:方阵(行数=列数)的原地交换转置
如果你的二维ArrayList是方阵(行数等于列数),可以直接在原结构上通过交换元素完成转置,不需要额外创建ArrayList:
int n = A.size(); // 只遍历上三角区域,避免重复交换 for (int i = 0; i < n; i++) { // j从i+1开始,跳过对角线和已交换过的元素 for (int j = i + 1; j < n; j++) { // 交换A[i][j]和A[j][i] Object temp = A.get(i).get(j); A.get(i).set(j, A.get(j).get(i)); A.get(j).set(i, temp); } }
这里直接通过get和set操作内层List的元素即可,因为要交换的是内层List中的元素,不是外层List的行,比用Collections.swap更直观。
方案2:矩形矩阵(行数≠列数)的无额外外层ArrayList实现
如果是矩形矩阵(比如n行m列,n≠m),转置后是m行n列,需要先调整外层List的结构,再填充元素。可以复用原有的外层ArrayList,清空后重新构建行,不需要额外创建新的外层List:
int rows = A.size(); if (rows == 0) return; int cols = A.get(0).size(); // 先保存原矩阵的完整数据,避免清空后丢失 List<List<Object>> originalMatrix = new ArrayList<>(A); // 清空原外层List,复用它存储转置后的行 A.clear(); // 创建转置后的每一行(共cols行) for (int i = 0; i < cols; i++) { A.add(new ArrayList<>()); } // 遍历原矩阵元素,放到转置后的对应位置 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { A.get(j).add(originalMatrix.get(i).get(j)); } }
注:矩形矩阵转置无法完全不占用额外空间,因为结构要调整,但可以复用外层List对象,仅用临时空间保存原矩阵数据。
内容的提问来源于stack exchange,提问作者mahe59ab
相关产品推荐
相关产品推荐

