Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions 2021-11-26 动态规划例题题解.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
layout: post
title: 算法-动态规划
date: 2021-11-19
author: 张书翌
categories:
- 数据分析部
tags:
- 动态规划的python实现
---
## ***动态规划***
#### 例题
一条包含字母 A-Z 的消息通过以下映射进行了编码 :
> A => 1
> B => 2
> ...
> Z => 26

要解码已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。
例如,"11106" 可以映射为:
* "AAJF" ,将消息分组为 (1 1 10 6)
* "KJF" ,将消息分组为 (11 10 6)

注意,消息不能分组为 (1 11 06) ,因为 "06" 不能映射为 "F" ,这是由于 "6" 和 "06" 在映射中并不等价。
给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数 。
题目数据保证答案肯定是一个 32 位 的整数。

***
#### 题解
> ### ***Step 1***
> Definition of dp[i]
> 我们将dp[i]定义为,字符串自0至i号位,有多少种***解码方式***
>
> ### ***Step 2***
> Set up of ***state transition fumula***
> 即 如何用以前dp中 *0到 i-1* 中储存的数据,以求解dp[i]
> 由于数字位数的特殊性,dp[i]的求解显然需要分类讨论
> 比如,若s[i]=="0",则它只能与前一位组合解码
> 而s[i]为其他时,则有分别解码的可能

* ***Case one***
> When ***s[i] == "0"***
> 由于它必须与前一位联合解码,所以有:
> If ***s[i-1] == "1” or "2"***,
>  
> ***dp[i] = dp[i-2]***
> else
>  
> ***dp[i] = 0***
* ***Case two***
> When ***s[i] == "1" or "2" or ... "6"***
> 由于它可以单独解码,所以有:
> ***dp[i] += dp[i-1]***
> 还需要进一步细分,关于s[i]能否与s[i-1]联合解码
> ***( i )***
>  如果***s[i-1]=="1" or "2"***,
>  那么***dp[i] += dp[i-2]***
> ***( ii )***
>  如果是其他情况,
>  那么***dp[i] remain unchanged***
* ***Case three***
> When ***s[i] == "6" or "7" or ... "9"***
> 由于它可以单独解码,所以有:
> ***dp[i] += dp[i-1]***
> 还需要进一步细分,关于s[i]能否与s[i-1]联合解码
> ***( i )***
>  如果***s[i-1] == "2"***,
>  那么***dp[i] += dp[i-2]***
> ***( ii )***
>  如果是其他情况,
>  那么***dp[i] remain unchanged***

***
#### 优化部分
> 由于求解 ***dp[i]*** 只用到了前两位的数据,
> 所以使用如下方式,将 ***空间复杂度*** 从O(n) 优化到 O(1) :
> 使用滚动数组的形式,具体地,cur,pre1,pre2交错覆盖


---
代码如下:
```python
class Solution:
def numDecodings(self, s: str) -> int:
n = len(s)
s = ' ' + s
f = [0] * 3
f[0] = 1
for i in range(1,n + 1):
f[i % 3] = 0
a = ord(s[i]) - ord('0')
b = ( ord(s[i - 1]) - ord('0') ) * 10 + ord(s[i]) - ord('0')
if 1 <= a <= 9:
f[i % 3] = f[(i - 1) % 3]
if 10 <= b <= 26:
f[i % 3] += f[(i - 2) % 3]
return f[n % 3]
98 changes: 98 additions & 0 deletions 2021-11-26-动态规划例题题解.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
layout: post
title: 算法-动态规划
date: 2021-11-19
author: 张书翌
categories:
- 数据分析部
tags:
- 动态规划的python实现
---
## ***动态规划***
#### 例题
一条包含字母 A-Z 的消息通过以下映射进行了编码 :
> A => 1
> B => 2
> ...
> Z => 26

要解码已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。
例如,"11106" 可以映射为:
* "AAJF" ,将消息分组为 (1 1 10 6)
* "KJF" ,将消息分组为 (11 10 6)

注意,消息不能分组为 (1 11 06) ,因为 "06" 不能映射为 "F" ,这是由于 "6" 和 "06" 在映射中并不等价。
给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数 。
题目数据保证答案肯定是一个 32 位 的整数。

***

#### 题解
> ### ***Step 1***
> Definition of dp[i]
> 我们将dp[i]定义为,字符串自0至i号位,有多少种***解码方式***
>
> ### ***Step 2***
> Set up of ***state transition fumula***
> 即 如何用以前dp中 *0到 i-1* 中储存的数据,以求解dp[i]
> 由于数字位数的特殊性,dp[i]的求解显然需要分类讨论
> 比如,若s[i]=="0",则它只能与前一位组合解码
> 而s[i]为其他时,则有分别解码的可能

* ***Case one***
> When ***s[i] == "0"***
> 由于它必须与前一位联合解码,所以有:
> If ***s[i-1] == "1” or "2"***,
> &ensp;
> ***dp[i] = dp[i-2]***
> else
> &ensp;
> ***dp[i] = 0***
* ***Case two***
> When ***s[i] == "1" or "2" or ... "6"***
> 由于它可以单独解码,所以有:
> ***dp[i] += dp[i-1]***
> 还需要进一步细分,关于s[i]能否与s[i-1]联合解码
> ***( i )***
> &ensp;如果***s[i-1]=="1" or "2"***,
> &ensp;那么***dp[i] += dp[i-2]***
> ***( ii )***
> &ensp;如果是其他情况,
> &ensp;那么***dp[i] remain unchanged***
* ***Case three***
> When ***s[i] == "6" or "7" or ... "9"***
> 由于它可以单独解码,所以有:
> ***dp[i] += dp[i-1]***
> 还需要进一步细分,关于s[i]能否与s[i-1]联合解码
> ***( i )***
> &ensp;如果***s[i-1] == "2"***,
> &ensp;那么***dp[i] += dp[i-2]***
> ***( ii )***
> &ensp;如果是其他情况,
> &ensp;那么***dp[i] remain unchanged***

***
#### 优化部分
> 由于求解 ***dp[i]*** 只用到了前两位的数据,
> 所以使用如下方式,将 ***空间复杂度*** 从O(n) 优化到 O(1) :
> 我们可以使用滚动数组,即cur,pre1,pre2交错覆盖


---
代码如下:
```python
class Solution:
def numDecodings(self, s: str) -> int:
n = len(s)
s = ' ' + s
f = [0] * 3
f[0] = 1
for i in range(1,n + 1):
f[i % 3] = 0
a = ord(s[i]) - ord('0')
b = ( ord(s[i - 1]) - ord('0') ) * 10 + ord(s[i]) - ord('0')
if 1 <= a <= 9:
f[i % 3] = f[(i - 1) % 3]
if 10 <= b <= 26:
f[i % 3] += f[(i - 2) % 3]
return f[n % 3]
122 changes: 0 additions & 122 deletions README.md

This file was deleted.

Loading