手机的九宫格图案解锁总共能绘出多少种图案?LeetCode 351. Android Unlock Patterns
需要滿足的要求有:
至少經過四個點;
不能重復經過同一個點;
路徑上的中間點不能跳過(如從1到3一定會經過2);
如果中間的點是之前已經用過的,那么這個點就可以被跳過(如213,因為2已經被用過,1就可以越過2與3連接,132是不允許的)。
作者:linkwun
鏈接:https://www.zhihu.com/question/24905007/answer/29414497
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
?
我用python寫了段代碼,先計算出所有大于四個數字的所有排列組合,然后從中剃除穿過中間那個數字的組合,剩下的既為符合要求的代碼。
例如13組合是不可能存在的,因為它會穿過2,19組合也不可能存在,因為它會穿過5,總共有16個這樣的組合。
但是假如中間這個數字已經用過了,是可以穿過的,比如213,2已經用過了,1是可以穿過2與3連接的。
如此篩選以后,就得到正確答案389112了。
以下兩段codes可以看做是等價的,只是chain的效率更高:
iterlst = chain(*(permutations('123456789', i) for i in range(4, 10)))count = 0for i in iterlst:和
for permutation in ((permutations('123456789', i) for i in range(4, 10))):for item in permutation:print(item)后記:上面的解法并不夠通用,通用的解法就是回溯。回溯需要注意兩點:
1. 回溯過程中無非考慮相鄰兩個節點之間的關系,同時滿足兩個條件為合法:
a. 并沒有訪問過
b. (存在13這種跨越,但是2已經被訪問過了)或者不存在13這種跨越,這些跨越打個表就好
2. 利用對稱性優化
最后貼一下leetcode 的題目和codes:
----------------------------------------------
Given an Android?3x3?key lock screen and two integers?m?and?n, where 1 ≤ m ≤ n ≤ 9, count the total number of unlock patterns of the Android lock screen, which consist of minimum of?m?keys and maximum?n?keys.
?
Rules for a valid pattern:
?
?
Explanation:
| 1 | 2 | 3 | | 4 | 5 | 6 | | 7 | 8 | 9 |Invalid move:?4 - 1 - 3 - 6
Line 1 - 3 passes through key 2 which had not been selected in the pattern.
Invalid move:?4 - 1 - 9 - 2
Line 1 - 9 passes through key 5 which had not been selected in the pattern.
Valid move:?2 - 4 - 1 - 3 - 6
Line 1 - 3 is valid because it passes through key 2, which had been selected in the pattern
Valid move:?6 - 5 - 4 - 1 - 9 - 2
Line 1 - 9 is valid because it passes through key 5, which had been selected in the pattern.
?
Example:
Input: m = 1, n = 1 Output: 9----------------------------------------------
class Solution:def numberOfPatterns(self, m, n):cross = {(1,3):2,(3,1):2,(1,7):4,(7,1):4,(3,9):6,(9,3):6,(7,9):8,(9,7):8,(1,9):5,(9,1):5,(2,8):5,(8,2):5,(3,7):5,(7,3):5,(4,6):5,(6,4):5}visited = set()def dfs(x, k):if not k: return 1visited.add(x)cnt = sum(dfs(y, k-1) for y in range(1,10) if y not in visited and ((x,y) not in cross or ((x,y) in cross and cross[(x,y)] in visited)))visited.discard(x)return cntreturn sum(dfs(1,k)*4 + dfs(2,k)*4 + dfs(5,k) for k in range(m-1, n))?
總結
以上是生活随笔為你收集整理的手机的九宫格图案解锁总共能绘出多少种图案?LeetCode 351. Android Unlock Patterns的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Lesson 49 At the bu
- 下一篇: 一步带你了解C语言中++、--的使用方法