https://www.hackerrank.com/challenges/matrix-rotation-algo
又是一道耗了两小时以上的题,做完了才想起来,这不就是几年前在POJ上做过的一个同类问题么:置换群问题。
给定义一个MxN的矩阵,让你按照从外到内一圈圈地,逆时针旋转R次。如果你打算一次次地转,那就掉坑里了,因为这题的暴力算法比高效算法还难写对。
这其实是置换的一个特例,比如给你一个排列[2, 4, 1, 3],让你按照这个对应关系把长度为4的数组变换R次,问最后的结果。
想到了什么吗?当然是矩阵的快速幂啦!什么矩阵?一个01稀疏矩阵。
[2, 4, 1, 3]可以表示为:
[0 1 0 0]
[0 0 0 1]
[1 0 0 0]
[0 0 1 0]
联系大一学的线性代数知识,这就是这个置换操作对应的左乘变换啊(线性变换)。
把[a, b, c, d]通过一次变换变成了[b, d, a, c]。那么变一亿次之后是什么呢?实际上置换是有循环节的,不过无所谓,有快速幂就不用操心循环节了。
于是变换R次也就是把这矩阵求R次幂,于是快速幂算法就派上用场了。
这题也是类似,只不过构造这个变换矩阵麻烦点,你要看矩阵旋转一次是怎么对应的。得出矩阵以后,求幂就容易了。
时间O(N * M * log(R)),空间一样。
1 import re 2 3 def get2DMatrix(n, m, val): 4 return [[val for j in xrange(m)] for i in xrange(n)] 5 6 def rotate(a, r): 7 # n is guaranteed to be even 8 n = len(a) 9 m = len(a[0]) 10 s = getDisplace(n, m) 11 s = displacePow(s, r) 12 b = get2DMatrix(n, m, 0) 13 for i in xrange(n): 14 for j in xrange(m): 15 b[i][j] = a[s[i * m + j] / m][s[i * m + j] % m] 16 return b 17 18 def getDisplace(n, m): 19 s = range(n * m) 20 i = 0 21 while i < n / 2 and i < m / 2: 22 rr = n - 2 * i 23 cc = m - 2 * i 24 for j in xrange(1, rr, 1): 25 #left 26 s[(j + i) * m + i] = (j - 1 + i) * m + i 27 for j in xrange(1, cc, 1): 28 #down 29 s[(rr - 1 + i) * m + (j + i)] = (rr - 1 + i) * m + (j - 1 + i) 30 for j in xrange(rr - 2, -1, -1): 31 #right 32 s[(j + i) * m + (cc - 1 + i)] = (j + 1 + i) * m + (cc - 1 + i) 33 for j in xrange(cc - 2, -1, -1): 34 #top 35 s[i * m + (j + i)] = i * m + (j + 1 + i) 36 i += 1 37 return s 38 39 def multiply(a, b): 40 n = len(a) 41 c = [] 42 for i in xrange(n): 43 c.append(a[b[i]]) 44 return c 45 46 def displacePow(a, k): 47 if k == 1: 48 return a[:] 49 a2 = displacePow(a, k >> 1) 50 if k & 1: 51 return multiply(multiply(a2, a2), a) 52 else: 53 return multiply(a2, a2) 54 55 if __name__ == '__main__': 56 n, m, r = map(int, re.split('\s+', raw_input().strip())) 57 a = [] 58 for i in xrange(n): 59 a.append(map(int, re.split('\s+', raw_input().strip()))) 60 a = rotate(a, r) 61 for i in xrange(n): 62 print(' '.join(map(str, a[i]))) 63
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)