Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[pull] main from itcharge:main #64

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
pull merged 9 commits into AlgorithmAndLeetCode:main from itcharge:main
Mar 11, 2023
Merged
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
3 changes: 2 additions & 1 deletion .gitignore
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,5 @@ dmypy.json

# Custom
Temp
.idea
.idea
.DS_Store
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,19 @@ def recursion(大规模问题):

### 4.2 避免重复运算

在使用递归算法时,还可能会出现重复运算的问题。比如斐波那契数列的定义是:`f(1) = 1, f(2) = 2, f(n) = f(n - 1) + f(n - 2)`。对应的递推过程如下图所示:
在使用递归算法时,还可能会出现重复运算的问题。

![](https://qcdn.itcharge.cn/images/20220408142726.png)
比如斐波那契数列的定义是:

从图中,我们可以看到:想要计算 `f(5)`,需要先计算 `f(4)` 和 `f(3)`,而在计算 `f(4)` 时还需要计算 `f(3)`。这样 `f(3)` 就进行了多次计算,这就是重复计算问题。
$f(n) = \begin{cases} 0 & n = 0 \cr 1 & n = 1 \cr f(n - 2) + f(n - 1) & n > 1 \end{cases}$

为了避免重复计算,我们可以使用哈希表、集合、列表等结构来保存已经求解过的 `f(k)` 的结果。当递归调用用到 `f(k)` 时,先查看一下之前是否已经计算过结果,如果已经计算过,则直接从对应结构中取值返回,而不用再递推下去,这样就避免了重复计算问题。
其对应的递归过程如下图所示:

![](https://qcdn.itcharge.cn/images/20230307164107.png)

从图中可以看出:想要计算 $f(5),ドル需要先计算 $f(3)$ 和 $f(4),ドル而在计算 $f(4)$ 时还需要计算 $f(3),ドル这样 $f(3)$ 就进行了多次计算。同理 $f(0)$、$f(1)$、$f(2)$ 都进行了多次计算,就导致了重复计算问题。

为了避免重复计算,我们可以使用一个缓存(哈希表、集合或数组)来保存已经求解过的 $f(k)$ 的结果,这也是动态规划算法中的做法。当递归调用用到 $f(k)$ 时,先查看一下之前是否已经计算过结果,如果已经计算过,则直接从缓存中取值返回,而不用再递推下去,这样就避免了重复计算问题。

## 5. 递归的应用

Expand Down
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@

换句话说,贪心算法不从整体最优上加以考虑,而是一步一步进行,每一步只以当前情况为基础,根据某个优化测度做出局部最优选择,从而省去了为找到最优解要穷举所有可能所必须耗费的大量时间。

对许多问题来说,可以使用贪心算法,通过局部最优解而得到整体最优解或者是整体最优解的近似解。
### 1.2 贪心算法的特征

但并不是所有问题,都可以使用贪心算法的。
对许多问题来说,可以使用贪心算法,通过局部最优解而得到整体最优解或者是整体最优解的近似解。但并不是所有问题,都可以使用贪心算法的。

一般来说,这些能够使用贪心算法解决的问题必须满足下面的两个特征:

1. **贪心选择性质**
2. **最优子结构**

### 1.2 贪心算法的特征

#### 1.2.1 贪心选择性质

> **贪心选择**:指的是一个问题的全局最优解可以通过一系列局部最优解(贪心选择)来得到。
Expand Down
24 changes: 12 additions & 12 deletions Contents/09.Algorithm-Base/06.Bit-Operation/01.Bit-Operation.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ $\begin{aligned} 106 \div 2 = 53 & \text{(余 0)} \cr 53 \div 2 = 26 & \text

我们先来看下这 6ドル$ 种位运算的规则,再来进行详细讲解。

| 运算符 | 描述 | 规则 |
| ------ | -------------- | ------------------------------------------------------------ |
| `&` | 按位与运算符 | 只有对应的两个二进位都为 1ドル$ 时,结果位才为 1ドル$。 |
| `|` | 按位或运算符 | 只要对应的两个二进位有一个为 1ドル$ 时,结果位就为 1ドル$。 |
| `^` | 按位异或运算符 | 对应的两个二进位相异时,结果位为 1ドル,ドル二进位相同时则结果位为 0ドル$。 |
| `~` | 取反运算符 | 对二进制数的每个二进位取反,使数字 1ドル$ 变为 0ドル,ドル0ドル$ 变为 1ドル$。 |
| `<<` | 左移运算符 | 将二进制数的各个二进位全部左移若干位。`<<` 右侧数字指定了移动位数,高位丢弃,低位补 0ドル$。 |
| `>>` | 右移运算符 | 对二进制数的各个二进位全部右移若干位。`>>` 右侧数字指定了移动位数,低位丢弃,高位补 0ドル$。 |
| 运算符 | 描述 | 规则 |
| ------------------- | -------------- | ------------------------------------------------------------ |
| `&` | 按位与运算符 | 只有对应的两个二进位都为 1ドル$ 时,结果位才为 1ドル$。 |
| <code>&#124;</code> | 按位或运算符 | 只要对应的两个二进位有一个为 1ドル$ 时,结果位就为 1ドル$。 |
| `^` | 按位异或运算符 | 对应的两个二进位相异时,结果位为 1ドル,ドル二进位相同时则结果位为 0ドル$。 |
| `~` | 取反运算符 | 对二进制数的每个二进位取反,使数字 1ドル$ 变为 0ドル,ドル0ドル$ 变为 1ドル$。 |
| `<<` | 左移运算符 | 将二进制数的各个二进位全部左移若干位。`<<` 右侧数字指定了移动位数,高位丢弃,低位补 0ドル$。 |
| `>>` | 右移运算符 | 对二进制数的各个二进位全部右移若干位。`>>` 右侧数字指定了移动位数,低位丢弃,高位补 0ドル$。 |

### 2.1 按位与运算

Expand Down Expand Up @@ -265,23 +265,23 @@ class Solution:

那么我们就可以用一个长度为 $n$ 的二进制数来表示集合 $S$ 或者表示 $S$ 的子集。其中二进制的每一个二进位都对应了集合中某一个元素的选取状态。对于集合中第 $i$ 个元素来说,二进制对应位置上的 1ドル$ 代表该元素被选取,0ドル$ 代表该元素未被选取。

举个例子,比如长度为 5ドル$ 的集合 $S = \left \{ 5, 4, 3, 2, 1 \right \},ドル我们可以用一个长度为 5ドル$ 的二进制数来表示该集合。
举个例子,比如长度为 5ドル$ 的集合 $S = \lbrace 5, 4, 3, 2, 1 \rbrace,ドル我们可以用一个长度为 5ドル$ 的二进制数来表示该集合。

比如二进制数 11111ドル_{(2)}$ 就表示选取集合的第 1ドル$ 位、第 2ドル$ 位、第 3ドル$ 位、第 4ドル$ 位、第 5ドル$ 位元素,也就是集合 $\left \{ 5, 4, 3, 2, 1 \right \},ドル即集合 $S$ 本身。如下表所示:
比如二进制数 11111ドル_{(2)}$ 就表示选取集合的第 1ドル$ 位、第 2ドル$ 位、第 3ドル$ 位、第 4ドル$ 位、第 5ドル$ 位元素,也就是集合 $\lbrace 5, 4, 3, 2, 1 \rbrace,ドル即集合 $S$ 本身。如下表所示:

| 集合 S 中元素位置 | 5 | 4 | 3 | 2 | 1 |
| :---------------- | :--: | :--: | :--: | :--: | :--: |
| 二进位对应值 | 1 | 1 | 1 | 1 | 1 |
| 对应选取状态 | 选取 | 选取 | 选取 | 选取 | 选取 |

再比如二进制数 10101ドル_{(2)}$ 就表示选取集合的第 1ドル$ 位、第 3ドル$ 位、第 5ドル$ 位元素,也就是集合 $\left \{5, 3, 1 \right \}$。如下表所示:
再比如二进制数 10101ドル_{(2)}$ 就表示选取集合的第 1ドル$ 位、第 3ドル$ 位、第 5ドル$ 位元素,也就是集合 $\lbrace 5, 3, 1 \rbrace$。如下表所示:

| 集合 S 中元素位置 | 5 | 4 | 3 | 2 | 1 |
| :---------------- | :--: | :----: | :--: | :----: | :--: |
| 二进位对应值 | 1 | 0 | 1 | 0 | 1 |
| 对应选取状态 | 选取 | 未选取 | 选取 | 未选取 | 选取 |

再比如二进制数 01001ドル_{(2)}$ 就表示选取集合的第 1ドル$ 位、第 4ドル$ 位元素,也就是集合 $\left \{4, 1 \right \}$。如下标所示:
再比如二进制数 01001ドル_{(2)}$ 就表示选取集合的第 1ドル$ 位、第 4ドル$ 位元素,也就是集合 $\lbrace 4, 1 \rbrace$。如下标所示:

| 集合 S 中元素位置 | 5 | 4 | 3 | 2 | 1 |
| :---------------- | :----: | :--: | :----: | :----: | :--: |
Expand Down
Loading

AltStyle によって変換されたページ (->オリジナル) /