嵌套循环交换列表变量异常:如何原地顺时针旋转二维方阵?
原地顺时针旋转二维方阵(O(1)额外内存)
问题背景
现有3x3二维方阵:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
希望顺时针旋转90度得到:
[[7, 4, 1], [8, 5, 2], [9, 6, 3]]
已能通过以下代码正确打印旋转后的结果:
for i in range(0, len(a)): for j in range(len(a), 0, -1): print(f"{a[j-1][i]}", end=",") print()
输出:
7,4,1, 8,5,2, 9,6,3,
但尝试原地修改列表时得到错误结果:
for i in range(0, len(a)): x = 0 for j in range(len(a), 0, -1): # 无临时变量交换 a[i][x], a[j-1][i] = a[j-1][i], a[i][x] x += 1 print(a)
输出:
[[3, 6, 1], [8, 5, 2], [9, 4, 7]]
问题出在元素被多次修改,现需要一种仅使用O(1)额外内存的原地实现方法。
解决方案
方法1:转置矩阵 + 反转每行
这是最直观的原地实现方式,步骤清晰且易于理解:
- 先对矩阵进行转置(行与列互换)
- 反转每一行的元素
代码实现:
a = [[1,2,3],[4,5,6],[7,8,9]] n = len(a) # 转置矩阵(仅遍历上三角避免重复交换) for i in range(n): for j in range(i, n): a[i][j], a[j][i] = a[j][i], a[i][j] # 反转每一行 for row in a: row.reverse() print(a)
输出:
[[7, 4, 1], [8, 5, 2], [9, 6, 3]]
方法2:分层交换四个角元素
对于n阶方阵,可按层从外层到内层处理,每层中一次性交换四个对应位置的元素,避免重复修改。以3x3矩阵为例,外层需处理两组四元素,中间元素无需变动。
代码实现:
a = [[1,2,3],[4,5,6],[7,8,9]] n = len(a) for layer in range(n // 2): first = layer last = n - 1 - layer for i in range(first, last): offset = i - first # 保存左上角元素 top = a[first][i] # 左下角移到左上角 a[first][i] = a[last - offset][first] # 右下角移到左下角 a[last - offset][first] = a[last][last - offset] # 右上角移到右下角 a[last][last - offset] = a[i][last] # 原左上角元素移到右上角 a[i][last] = top print(a)
输出:
[[7, 4, 1], [8, 5, 2], [9, 6, 3]]
原错误方法分析
你之前的遍历方式会在修改元素后,后续循环再次使用已被修改的值,导致元素被多次交换,最终顺序混乱。比如第一次循环修改了a[0][0],后续循环中这个位置的新值又会参与交换,破坏了原本的映射关系。而上面两种方法都规避了这个问题:转置+反转通过两次独立遍历完成,分层交换则一次性处理四个对应位置,每个元素仅被移动一次。
内容的提问来源于stack exchange,提问作者Lucky
相关产品推荐
相关产品推荐

