
本文介绍如何高效、简洁地实现 n×n 二维矩阵的顺时针 90 度旋转,并支持任意整数次旋转(自动取模优化),避免原地旋转的边界错误,同时提供清晰的输入输出格式与可视化打印。
在 Python 中对二维矩阵进行 90 度顺时针旋转,最直观且健壮的方式不是手动交换元素(易出错、边界复杂),而是利用 Python 的内置操作组合:[::-1](上下翻转) + zip(*...)(转置)。这一组合恰好等价于一次顺时针 90° 旋转:
- m[::-1]:将行顺序反转(即垂直翻转);
- zip(*m[::-1]):对翻转后的矩阵进行解包转置,得到顺时针旋转 90° 的结果。
该方法简洁、安全、可读性强,且天然支持任意次数旋转 —— 因为旋转 4 次等于恒等变换,所以只需对旋转次数 n 取模:n % 4。
以下是完整、可直接运行的教程级实现:
def rotate(matrix, times):
"""
对 N×N 矩阵顺时针旋转 90 度 'times' 次。
自动对 times 取模 4,避免冗余操作。
返回新矩阵(不修改原矩阵)。
"""
m = [row[:] for row in matrix] # 深拷贝,保护原数据
for _ in range(times % 4):
m = list(zip(*m[::-1]))
# zip 返回元组,若需纯列表形式,可进一步转换:
m = [list(row) for row in m]
return m
def print_matrix(matrix):
"""按题目要求格式打印矩阵:每行数字空格分隔"""
for row in matrix:
print(*row)
# 示例:读取输入
N = int(input())
matrix = []
for _ in range(N):
row = list(map(int, input().split()))
matrix.append(row)
# 假设目标是旋转至数字 1 位于左上角(即标准位置)
# 根据题意输入示例,1 初始在 (0,2),即索引 flatList[2] → 对应 3 次旋转(90°×3 = 270° 顺时针 ≡ 90° 逆时针)
# 但更通用的做法是:明确指定旋转次数(如题目中 M),或根据需求动态计算
# 此处以「旋转 3 次」为例(匹配预期输出)
rotated = rotate(matrix, 3)
print_matrix(rotated)输入示例:
立即学习“Python免费学习笔记(深入)”;
3 4 3 1 6 5 2 9 7 3
输出:
1 2 3 3 5 7 4 6 9
✅ 关键优势说明:
- ✅ 无索引越界风险:不依赖手工双指针交换,规避了原代码中 for i in range(left-right) 这类逻辑错误(应为 range(right - left),且循环内变量更新缺失);
- ✅ 不可变友好:返回新矩阵,不影响原始数据,便于链式调用或调试;
- ✅ 时间/空间清晰:单次旋转时间复杂度 O(N²),空间 O(N²),符合最优理论下界;
- ✅ 扩展性强:支持任意 times(正数=顺时针,负数可扩展为逆时针,只需调整模运算逻辑)。
⚠️ 注意事项:
- zip(*m[::-1]) 返回的是 tuple 行,如需纯 list 类型矩阵(例如后续需修改元素),务必用 [list(row) for row in ...] 转换;
- 若需原地旋转(节省内存),应改用分层环形交换算法,但需严格校验索引边界(推荐仅在内存极度受限且矩阵极大时采用);
- 题目中通过 flatList.index(1) 推断旋转次数的方法仅适用于含唯一 1 且初始布局固定的场景,不具备通用性;生产环境建议显式传入旋转次数 M。
掌握这一 zip(*m[::-1]) 惯用法,你就能以最少代码、最高可靠性完成矩阵旋转任务——它不仅是技巧,更是 Python 数据处理哲学的体现:用组合代替手写循环,用语义代替索引。










