Skip to content

Commit 90b3883

Browse files
committed
feat: update leetcode solutions: No.0091. Decode Ways
1 parent 9945e3c commit 90b3883

File tree

6 files changed

+173
-13
lines changed

6 files changed

+173
-13
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@
156156
- [接雨水](/solution/0000-0099/0042.Trapping%20Rain%20Water/README.md)
157157
- [最大子序和](/solution/0000-0099/0053.Maximum%20Subarray/README.md)
158158
- [礼物的最大价值](/lcof/面试题47.%20礼物的最大价值/README.md)
159+
- [解码方法](/solution/0000-0099/0091.Decode%20Ways/README.md)
159160
- [乘积最大子序列](/solution/0100-0199/0152.Maximum%20Product%20Subarray/README.md)
160161
- [打家劫舍](/solution/0100-0199/0198.House%20Robber/README.md)
161162
- [打家劫舍 II](/solution/0200-0299/0213.House%20Robber%20II/README.md)

README_EN.md

+1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ Complete solutions to [LeetCode](https://leetcode-cn.com/problemset/all/), [LCOF
149149
- [Climbing Stairs](/solution/0000-0099/0070.Climbing%20Stairs/README_EN.md)
150150
- [Trapping Rain Water](/solution/0000-0099/0042.Trapping%20Rain%20Water/README_EN.md)
151151
- [Maximum Subarray](/solution/0000-0099/0053.Maximum%20Subarray/README_EN.md)
152+
- [Decode Ways](/solution/0000-0099/0091.Decode%20Ways/README_EN.md)
152153
- [Maximum Product Subarray](/solution/0100-0199/0152.Maximum%20Product%20Subarray/README_EN.md)
153154
- [House Robber](/solution/0100-0199/0198.House%20Robber/README_EN.md)
154155
- [House Robber II](/solution/0200-0299/0213.House%20Robber%20II/README_EN.md)

solution/0000-0099/0091.Decode Ways/README.md

+78
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,100 @@
3333

3434
<!-- 这里可写通用的实现逻辑 -->
3535

36+
动态规划法。
37+
38+
假设 `dp[i]` 表示字符串 s 的前 i 个字符 `s[1..i]` 的解码方法数。
39+
40+
考虑最后一次解码中使用了 s 中的哪些字符:
41+
42+
- 第一种情况是我们使用了一个字符,即 `s[i]` 进行解码,那么只要 `s[i]≠0`,它就可以被解码成 `A∼I` 中的某个字母。由于剩余的前 `i-1` 个字符的解码方法数为 `dp[i-1]`,所以 `dp[i] = dp[i-1]`
43+
- 第二种情况是我们使用了两个字符,即 `s[i-1]``s[i]` 进行编码。与第一种情况类似,`s[i-1]` 不能等于 0,并且 `s[i-1]``s[i]` 组成的整数必须小于等于 26,这样它们就可以被解码成 `J∼Z` 中的某个字母。由于剩余的前 `i-2` 个字符的解码方法数为 `dp[i-2]`,所以 `dp[i] = dp[i-2]`
44+
45+
将上面的两种状态转移方程在对应的条件满足时进行累加,即可得到 `dp[i]`的值。在动态规划完成后,最终的答案即为 `dp[n]`
46+
47+
由于 `dp[i]` 的值仅与 `dp[i-1]``dp[i-2]` 有关,因此可以不定义 dp 数组,可以仅使用三个变量进行状态转移。
48+
3649
<!-- tabs:start -->
3750

3851
### **Python3**
3952

4053
<!-- 这里可写当前语言的特殊实现逻辑 -->
4154

4255
```python
56+
class Solution:
57+
def numDecodings(self, s: str) -> int:
58+
n = len(s)
59+
dp = [0] * (n + 1)
60+
dp[0] = 1
61+
for i in range(1, n + 1):
62+
if s[i - 1] != '0':
63+
dp[i] += dp[i - 1]
64+
if i > 1 and s[i - 2] != '0' and (int(s[i - 2]) * 10 + int(s[i - 1]) <= 26):
65+
dp[i] += dp[i - 2]
66+
return dp[n]
67+
```
68+
69+
优化空间:
4370

71+
```python
72+
class Solution:
73+
def numDecodings(self, s: str) -> int:
74+
n = len(s)
75+
a, b, c = 0, 1, 0
76+
for i in range(1, n + 1):
77+
c = 0
78+
if s[i - 1] != '0':
79+
c += b
80+
if i > 1 and s[i - 2] != '0' and (int(s[i - 2]) * 10 + int(s[i - 1]) <= 26):
81+
c += a
82+
a, b = b, c
83+
return c
4484
```
4585

4686
### **Java**
4787

4888
<!-- 这里可写当前语言的特殊实现逻辑 -->
4989

5090
```java
91+
class Solution {
92+
public int numDecodings(String s) {
93+
int n = s.length();
94+
int[] dp = new int[n + 1];
95+
dp[0] = 1;
96+
for (int i = 1; i <= n; ++i) {
97+
if (s.charAt(i - 1) != '0') {
98+
dp[i] += dp[i - 1];
99+
}
100+
if (i > 1 && s.charAt(i - 2) != '0' && ((s.charAt(i - 2) - '0') * 10 + s.charAt(i - 1) - '0') <= 26) {
101+
dp[i] += dp[i - 2];
102+
}
103+
}
104+
return dp[n];
105+
}
106+
}
107+
```
108+
109+
优化空间:
51110

111+
```java
112+
class Solution {
113+
public int numDecodings(String s) {
114+
int n = s.length();
115+
int a = 0, b = 1, c = 0;
116+
for (int i = 1; i <= n; ++i) {
117+
c = 0;
118+
if (s.charAt(i - 1) != '0') {
119+
c += b;
120+
}
121+
if (i > 1 && s.charAt(i - 2) != '0' && ((s.charAt(i - 2) - '0') * 10 + s.charAt(i - 1) - '0') <= 26) {
122+
c += a;
123+
}
124+
a = b;
125+
b = c;
126+
}
127+
return c;
128+
}
129+
}
52130
```
53131

54132
### **...**

solution/0000-0099/0091.Decode Ways/README_EN.md

+69
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,83 @@
4848

4949
### **Python3**
5050

51+
Solution1:
52+
5153
```python
54+
class Solution:
55+
def numDecodings(self, s: str) -> int:
56+
n = len(s)
57+
dp = [0] * (n + 1)
58+
dp[0] = 1
59+
for i in range(1, n + 1):
60+
if s[i - 1] != '0':
61+
dp[i] += dp[i - 1]
62+
if i > 1 and s[i - 2] != '0' and (int(s[i - 2]) * 10 + int(s[i - 1]) <= 26):
63+
dp[i] += dp[i - 2]
64+
return dp[n]
65+
```
5266

67+
Solution2:
68+
69+
```python
70+
class Solution:
71+
def numDecodings(self, s: str) -> int:
72+
n = len(s)
73+
a, b, c = 0, 1, 0
74+
for i in range(1, n + 1):
75+
c = 0
76+
if s[i - 1] != '0':
77+
c += b
78+
if i > 1 and s[i - 2] != '0' and (int(s[i - 2]) * 10 + int(s[i - 1]) <= 26):
79+
c += a
80+
a, b = b, c
81+
return c
5382
```
5483

5584
### **Java**
5685

86+
Solution1:
87+
5788
```java
89+
class Solution {
90+
public int numDecodings(String s) {
91+
int n = s.length();
92+
int[] dp = new int[n + 1];
93+
dp[0] = 1;
94+
for (int i = 1; i <= n; ++i) {
95+
if (s.charAt(i - 1) != '0') {
96+
dp[i] += dp[i - 1];
97+
}
98+
if (i > 1 && s.charAt(i - 2) != '0' && ((s.charAt(i - 2) - '0') * 10 + s.charAt(i - 1) - '0') <= 26) {
99+
dp[i] += dp[i - 2];
100+
}
101+
}
102+
return dp[n];
103+
}
104+
}
105+
```
58106

107+
Solution2:
108+
109+
```java
110+
class Solution {
111+
public int numDecodings(String s) {
112+
int n = s.length();
113+
int a = 0, b = 1, c = 0;
114+
for (int i = 1; i <= n; ++i) {
115+
c = 0;
116+
if (s.charAt(i - 1) != '0') {
117+
c += b;
118+
}
119+
if (i > 1 && s.charAt(i - 2) != '0' && ((s.charAt(i - 2) - '0') * 10 + s.charAt(i - 1) - '0') <= 26) {
120+
c += a;
121+
}
122+
a = b;
123+
b = c;
124+
}
125+
return c;
126+
}
127+
}
59128
```
60129

61130
### **...**
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
class Solution {
22
public int numDecodings(String s) {
3-
int len = s.length();
4-
if (len == 0) return 0;
5-
int current = s.charAt(0) == '0' ? 0 : 1;
6-
int last = 1;
7-
for (int i = 1; i < len; i++) {
8-
int tmp = current;
9-
if(s.charAt(i) == '0'){
10-
if(s.charAt(i-1) == '1' || s.charAt(i-1) == '2') current = last;
11-
else return 0;
12-
}else if(s.charAt(i-1) == '1' || s.charAt(i-1) == '2' && s.charAt(i) <= '6') {
13-
current += last;
3+
int n = s.length();
4+
int a = 0, b = 1, c = 0;
5+
for (int i = 1; i <= n; ++i) {
6+
c = 0;
7+
if (s.charAt(i - 1) != '0') {
8+
c += b;
149
}
15-
last = tmp;
10+
if (i > 1 && s.charAt(i - 2) != '0' && ((s.charAt(i - 2) - '0') * 10 + s.charAt(i - 1) - '0') <= 26) {
11+
c += a;
12+
}
13+
a = b;
14+
b = c;
1615
}
17-
return current;
16+
return c;
1817
}
1918
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Solution:
2+
def numDecodings(self, s: str) -> int:
3+
n = len(s)
4+
a, b, c = 0, 1, 0
5+
for i in range(1, n + 1):
6+
c = 0
7+
if s[i - 1] != '0':
8+
c += b
9+
if i > 1 and s[i - 2] != '0' and (int(s[i - 2]) * 10 + int(s[i - 1]) <= 26):
10+
c += a
11+
a, b = b, c
12+
return c

0 commit comments

Comments
 (0)