forked from itcharge/AlgoNote
-
Notifications
You must be signed in to change notification settings - Fork 0
[pull] main from itcharge:main #93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
6a8de97
Update 1994. 好子集的数目.md
itcharge 3900d0a
Create 0935. 骑士拨号器.md
itcharge 552ec55
Update 0351. 安卓系统手势解锁.md
itcharge be60c9c
Create 1349. 参加考试的最大学生数.md
itcharge af2af20
Create 0698. 划分为k个相等的子集.md
itcharge 1238859
更新题解列表
itcharge File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Create 0935. 骑士拨号器.md
- Loading branch information
There are no files selected for viewing
108 changes: 108 additions & 0 deletions
Solutions/0935. 骑士拨号器.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# [0935. 骑士拨号器](https://leetcode.cn/problems/knight-dialer/) | ||
|
||
- 标签:动态规划 | ||
- 难度:中等 | ||
|
||
## 题目大意 | ||
|
||
**描述**:象棋骑士可以垂直移动两个方格,水平移动一个方格,或者水平移动两个方格,垂直移动一个方格(两者都形成一个 $L$ 的形状),如下图所示。 | ||
|
||
 | ||
|
||
现在我们有一个象棋其实和一个电话垫,如下图所示,骑士只能站在一个数字单元格上(0ドル \sim 9$)。 | ||
|
||
 | ||
|
||
现在给定一个整数 $n$。 | ||
|
||
**要求**:返回我们可以拨多少个长度为 $n$ 的不同电话号码。因为答案可能很大,所以最终答案需要对 10ドル^9 + 7$ 进行取模。 | ||
|
||
**说明**: | ||
|
||
- 可以将骑士放在任何数字单元格上,然后执行 $n - 1$ 次移动来获得长度为 $n$ 的电话号码。 | ||
- 1ドル \le n \le 5000$。 | ||
|
||
**示例**: | ||
|
||
- 示例 1: | ||
|
||
```Python | ||
输入:n = 1 | ||
输出:10 | ||
解释:我们需要拨一个长度为1的数字,所以把骑士放在10个单元格中的任何一个数字单元格上都能满足条件。 | ||
``` | ||
|
||
- 示例 2: | ||
|
||
```Python | ||
输入:n = 2 | ||
输出:20 | ||
解释:我们可以拨打的所有有效号码为[04, 06, 16, 18, 27, 29, 34, 38, 40, 43, 49, 60, 61, 67, 72, 76, 81, 83, 92, 94] | ||
``` | ||
|
||
## 解题思路 | ||
|
||
### 思路 1:动态规划 | ||
|
||
根据象棋骑士的跳跃规则,以及电话键盘的样式,我们可以预先处理一下象棋骑士当前位置与下一步能跳跃到的位置关系,将其存入哈希表中,方便查询。 | ||
|
||
接下来我们可以用动态规划的方式,计算出跳跃 $n - 1$ 次总共能得到多少个长度为 $n$ 的不同电话号码。 | ||
|
||
###### 1. 划分阶段 | ||
|
||
按照步数、所处数字位置进行阶段划分。 | ||
|
||
###### 2. 定义状态 | ||
|
||
定义状态 $dp[i][v]$ 表示为:第 $i$ 步到达键位 $u$ 总共能到的长度为 $i + 1$ 的不同电话号码个数。 | ||
|
||
###### 3. 状态转移方程 | ||
|
||
第 $i$ 步到达键位 $v$ 所能得到的不同电话号码个数,取决于 $i - 1$ 步中所有能到达 $v$ 的键位 $u$ 的不同电话号码个数总和。 | ||
|
||
呢状态转移方程为:$dp[i][v] = \sum dp[i - 1][u]$(可以从 $u$ 跳到 $v$)。 | ||
|
||
###### 4. 初始条件 | ||
|
||
- 第 0ドル$ 步(位于开始位置)所能得到的电话号码个数为 1ドル,ドル因为开始时可以将骑士放在任何数字单元格上,所以所有的 $dp[0][v] = 1$。 | ||
|
||
###### 5. 最终结果 | ||
|
||
根据我们之前定义的状态,$dp[i][v]$ 表示为:第 $i$ 步到达键位 $u$ 总共能到的长度为 $i + 1$ 的不同电话号码个数。 所以最终结果为第 $n - 1$ 行所有的 $dp[n - 1][v]$ 的总和。 | ||
|
||
### 思路 1:代码 | ||
|
||
```Python | ||
class Solution: | ||
def knightDialer(self, n: int) -> int: | ||
graph = { | ||
0: [4, 6], | ||
1: [6, 8], | ||
2: [7, 9], | ||
3: [4, 8], | ||
4: [0, 3, 9], | ||
5: [], | ||
6: [0, 1, 7], | ||
7: [2, 6], | ||
8: [1, 3], | ||
9: [2, 4] | ||
} | ||
|
||
MOD = 10 ** 9 + 7 | ||
dp = [[0 for _ in range(10)] for _ in range(n)] | ||
for v in range(10): | ||
dp[0][v] = 1 | ||
|
||
for i in range(1, n): | ||
for u in range(10): | ||
for v in graph[u]: | ||
dp[i][v] = (dp[i][v] + dp[i - 1][u]) % MOD | ||
|
||
return sum(dp[n - 1]) % MOD | ||
``` | ||
|
||
### 思路 1:复杂度分析 | ||
|
||
- **时间复杂度**:$O(n \times 10),ドル其中 $n$ 为给定整数。 | ||
- **空间复杂度**:$O(n \times 10)$。 | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.