Java中用Collections.swap实现O(1)空间复杂度的方阵转置报错问题
为什么Collections.swap实现矩阵转置会抛出异常?
核心原因:完全用错了API的参数逻辑
Collections.swap(List<?> list, int i, int j)的作用是交换同一个列表中索引i和j位置的元素,它的第二个、第三个参数必须是整数类型的索引值,而不是元素本身。
看你的代码:
Collections.swap(originalArray,originalArray.get(row).get(col),originalArray.get(col).get(row));
这里你把矩阵中(row,col)和(col,row)位置的元素值当成索引传给了swap方法——比如如果矩阵元素是整数,假设元素值是10,但外层列表originalArray只有5行,那传入10作为索引直接就会抛出IndexOutOfBoundsException;就算元素值刚好在索引范围内,swap操作的也是外层列表中对应索引的整行,完全不是你要的交换矩阵内两个位置的元素。
额外误区:该API无法跨列表交换元素
矩阵转置时,(row,col)属于第row行的列表,(col,row)属于第col行的列表——这是两个不同的内层列表。而Collections.swap只能操作同一个列表里的元素,根本做不到跨列表交换元素,这也是为什么你用临时变量的写法能正常运行(临时变量直接操作两个不同列表的指定位置元素),但用swap完全走不通的原因。
正确的写法(如果非要用swap)
如果一定要用Collections.swap,只能针对单一行内的元素交换,但转置需要的是跨行交换,所以最终还是得结合临时变量,比如:
for(int row = 0; row < originalArray.size(); row++) { for(int col = row+1; col < originalArray.get(0).size(); col++) { List<?> rowList = originalArray.get(row); List<?> colList = originalArray.get(col); // 暂存元素,因为要跨两个列表交换 Object temp = rowList.get(col); // 把col行row位置的元素放到row行col位置 rowList.set(col, colList.get(row)); // 把暂存的元素放到col行row位置 colList.set(row, temp); } }
本质上这和你用临时变量的写法逻辑一致,只是没有用到swap——因为swap在这里确实派不上用场。
内容的提问来源于stack exchange,提问作者HK123
相关产品推荐
相关产品推荐

