Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
61 changes: 45 additions & 16 deletions src/0091.Decode-Ways/README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
# [1. Add Sum][title]

## Description

Given two binary strings, return their sum (also a binary string).

The input strings are both **non-empty** and contains only characters `1` or `0`.

一个只包含 A-Z 的消息可以用如下方式编码成数字:
```bash
'A' -> 1
'B' -> 2
...
'Z' -> 26
```
给定一个只包含数字的非空字符串,返回共有多少种解码方案。
**Example 1:**

```
Input: a = "11", b = "1"
Output: "100"
Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).
```

**Example 2:**

```
Input: a = "1010", b = "1011"
Output: "10101"
Input: "226"
Output: 3
Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
```

**Tags:** Math, String
Expand All @@ -28,16 +33,40 @@ Output: "10101"
## 题解

### 思路1
> 按照小学算数那么来做,用 `carry` 表示进位,从后往前算,依次往前,每算出一位就插入到最前面即可,直到把两个二进制串都遍历完即可。
> (动态规划) O(n)
>
这道题目可以用动态规划来做。
状态表示:f[i]f[i] 表示前 ii 个数字共有多少种解码方式。
初始化:0个数字解码的方案数1,即 f[0]=1f[0]=1。
状态转移:f[i]f[i] 可以表示成如下两部分的和:

```go

```
- 如果第 ii 个数字不是0,则 ii 个数字可以单独解码成一个字母,此时的方案数等于用前 i−1i−1 个数字解码的方案数,即 f[i−1]f[i−1];
- 如果第 i−1i−1个数字和第 ii 个数字组成的两位数在 1010 到 2626 之间,则可以将这两位数字解码成一个字符,此时的方案数等于用前 i−2i−2 个数字解码的方案数,即 f[i−2]f[i−2];
时间复杂度分析:状态数是 nn 个,状态转移的时间复杂度是 O(1)O(1),所以总时间复杂度是 O(n)O(n)。

### 思路2
> 思路2
```go

func numDecodings(s string) int {
n := len(s)
f := make([]int, n+1)
f[0] = 1

for i := 1; i <= n; i++ {
if s[i-1] < '0' || s[i-1] > '9' {
return 0
}
f[i] = 0
if s[i-1] != '0' {
f[i] = f[i-1]
}
if i > 1 {
t := (s[i-2]-'0')*10 + s[i-1] - '0'
if t >= 10 && t <= 26 {
f[i] += f[i-2]
}
}
}
return f[n]
}
```

## 结语
Expand Down
29 changes: 27 additions & 2 deletions src/0091.Decode-Ways/Solution.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
package Solution

func Solution(x bool) bool {
return x
func numDecodings(s string) int {
// 思路:
// 状态表示:f[i] i个数(最后一个数字是s[i-1])解码得到的所有字符串的数量 f[i]从0开始
// 状态计算: 集合可以分成:最后一个i是一位数,和最后一个i是两位数
// 之前想过的错误思路:f[i] 表示以i结尾的decode共有多少种解法
// 集合划分为不算i:f[i - j] + f[j] 和算i: f[i];
n := len(s)
//加一是为了方便边界特判
f := make([]int, n+1)
//空字符串特判
f[0] = 1
// 如果最后一个i是个位数 1 ~ 26
// 难点:如何转化char为int
for i := 1; i <= n; i++ { //从一开始是因为表示的是前多少个字母,不是下标从一开始的字母
//如果最后一个i是个位数,且不为0
if s[i-1] != '0' {
f[i] += f[i-1]
}
//如果最后一个i是两位数,且在1~26之间
if i >= 2 {
t := (s[i-2]-'0')*10 + s[i-1] - '0'
if t >= 10 && t <= 26 {
f[i] += f[i-2]
}
}
}
return f[n]
}
11 changes: 5 additions & 6 deletions src/0091.Decode-Ways/Solution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,17 @@ func TestSolution(t *testing.T) {
// 测试用例
cases := []struct {
name string
inputs bool
expect bool
inputs string
expect int
}{
{"TestCacse 1", true, true},
{"TestCacse 1", true, true},
{"TestCacse 1", false, false},
{"TestCacse 1", "12", 2},
{"TestCacse 1", "226", 3},
}

// 开始测试
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
ret := Solution(c.inputs)
ret := numDecodings(c.inputs)
if !reflect.DeepEqual(ret, c.expect) {
t.Fatalf("expected: %v, but got: %v, with inputs: %v",
c.expect, ret, c.inputs)
Expand Down