2018/11/11
935. Knight Dialer
问题描述:
A chess knight can move as indicated in the chess diagram below:
This time, we place our chess knight on any numbered key of a phone pad (indicated above), and the knight makes N-1hops. Each hop must be from one key to another numbered key.
Each time it lands on a key (including the initial placement of the knight), it presses the number of that key, pressing Ndigits total.
How many distinct numbers can you dial in this manner?
Since the answer may be large, output the answer modulo 10^9 + 7.
样例:
Example 1:
Input: 1
Output: 10
Example 2:
Input: 2
Output: 20
Example 3:
Input: 3
Output: 46
Note:
- 1 <= N <= 5000
问题分析:
本题难度为Medium!属于动态规划问题,已给出的函数定义为
class Solution:
def knightDialer(self, N):
"""
:type N: int
:rtype: int
"""
本题采取动态规划算法,每一步的电话数字与上一步的电话数字相关。nextNumbers本质上为一张查询表,nextNumber[i]存储了数字i下一步可以到达的数字;res[i]表示最后一步停留在数字i上的组合数(情况数),则sum(res)为最后输出,每一步都更新新的结果res=newRes;newRes是在上一步res的基础上当前这一步的结果。
代码实现:
#coding=utf-8
class Solution:
def knightDialer(self, N):
"""
:type N: int
:rtype: int
"""
#当前数字可以跳到的下一个数字,例:nextNumbers[0]=[4,6]表示0的可以跳到数字4或6
nextNumbers=[[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,3],[2,4]]
res = [1 for t in range(10)] #某一步数将走上其索引所在数字的所有情况的总数,初始化为第一步的结果
for i in range(1,N): #对于第i步
newRes = [0 for t in range(10)] #用来更新其总数情况。
for number in range(10):
for j in nextNumbers[number]:
newRes[j] += res[number]
res = newRes
return sum(res) % (10**9+7) #对输出取模