Skip to content

Commit

Permalink
bfs
Browse files Browse the repository at this point in the history
  • Loading branch information
yk committed Apr 2, 2024
1 parent b2904bc commit e9a92c5
Show file tree
Hide file tree
Showing 36 changed files with 228 additions and 38 deletions.
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"cSpell.words": [
"adjs"
]
}
2 changes: 1 addition & 1 deletion config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ count = 5

# 赞赏配置
[params.sponsor]
enable = true
enable = false
bio = "如果你觉得这篇文章对你有所帮助,欢迎赞赏~"
link = "/sponsor" # 你的赞赏页面的地址
custom = "" # 自定义 HTML
Expand Down
167 changes: 167 additions & 0 deletions content/posts/algorithm/trick/暴力递归-BFS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
---
title: '暴力递归-BFS'
date: 2022-10-09T20:49:13+08:00
lastmod: 2024-03-27
series: [trick]
categories: [algorithm]
---

## 概念

在学习二叉树的时候,层序遍历就是用 BFS 实现的。

从二叉树拓展到多叉树到图,从一个点开始,向四周开始扩散。一般来说,写 BFS 算法都是用「队列」这种数据结构,每次将一个节点周围的所有节点加入队列。

BFS 一大常见用途,就是找 start 到 target 的最近距离,要能把实际问题往这方面转。

```js
// 二叉树中 start 就是 root
function bfs(start, target) {
const queue = [start]
const visited = new Set()
visited.add(start)

let step = 0
while (queue.length > 0) {
const size = queue.length
for (let i = 0; i < size; ++i) {
const el = queue.shift()
if (el === target) return step // '需要的信息'
const adjs = el.adj() // 泛指获取到 el 的所有相邻元素
for (let j = 0; j < adjs.length; ++j) {
if (!visited.has(adjs[j])) {
queue.push(adjs[j])
visited.push(adjs[j])
}
}
}
step++
}
}
```

## 练习

### lc.111 二叉树的最小深度 easy

```js
/**
* 忍不住上来先来了个 dfs,但不是今天的主角哈😂 ps: 此处用了回溯的思想,也可以用转为子问题的思想
* @param {TreeNode} root
* @return {number}
*/
var minDepth = function (root) {
if (root === null) return 0
let min = Infinity
const dfs = (root, deep) => {
if (root == null) return
if (root.left == null && root.right == null) {
min = Math.min(min, deep)
return
}
deep++
dfs(root.left, deep)
deep--
deep++
dfs(root.right, deep)
deep--
}
dfs(root, 1)
return min
}
```

```js
/** BFS 版本 */
/**
* @param {TreeNode} root
* @return {number}
*/
var minDepth = function (root) {
// 这里求的就是 root 到 最近叶子结点(target)的距离,明确了这个,剩下的交给手吧~
if (root === null) return 0
const queue = [root]
let deep = 0
while (queue.length) {
const size = queue.length
deep++
for (let i = 0; i < size; ++i) {
const el = queue.shift()
if (el.left === null && el.right === null) return deep
if (el.left) queue.push(el.left)
if (el.right) queue.push(el.right)
}
}
return deep
}
```

不得不说,easy 面前还是有点底气的,😄。

### lc.752 打开转盘锁

这道题是中等题,but,真的有点难度,需要好好分析。

首先毫无疑问,是一个穷举题目,其次,题目一个重点是:**每次旋转都只能旋转一个拨轮的一位数字**,这样我们就能抽象出每个节点的相邻节点了, '0000', '1000','9000','0100','0900'......如是题目就转变成了从 '0000' 到 target 的最短路径问题了。

```js
/**
* @param {string[]} deadends
* @param {string} target
* @return {number}
*/
var openLock = function (deadends, target) {
const queue = ['0000']
let step = 0
const visited = new Set()
visited.add('0000')
while (queue.length) {
const size = queue.length
for (let i = 0; i < size; ++i) {
const el = queue.shift()
if (deadends.includes(el)) continue
if (el === target) return step
// 把相邻元素加入 queue
for (let j = 0; j < 4; j++) {
const up = plusOne(el, j)
const down = minusOne(el, j)
!visited.has(up) && queue.push(up), visited.add(up)
!visited.has(down) && queue.push(down), visited.add(down)
}
}
step++
}
return -1
}
// 首先定义 每个转盘 +1,-1 操作
function plusOne(str, i) {
const arr = str.split('')
if (arr[i] == '9') {
arr[i] = '0'
} else {
arr[i]++
}
return arr.join('')
}
function minusOne(str, i) {
const arr = str.split('')
if (arr[i] == '0') {
arr[i] = '9'
} else {
arr[i]--
}
return arr.join('')
}
```

> 提一下 「双向 BFS 优化」:传统的 BFS 框架就是从起点开始向四周扩散,遇到终点时停止;而双向 BFS 则是从起点和终点同时开始扩散,当两边有交集的时候停止。[labuladong](https://labuladong.online/algo/essential-technique/bfs-framework-2/#%E5%9B%9B%E3%80%81%E5%8F%8C%E5%90%91-bfs-%E4%BC%98%E5%8C%96)
### lc.773 滑动谜题

又是一个小时候玩过的经典小游戏。

这道题的难点是,初学者是真的想不到怎么做,知道用什么方法的也在把实际问题转为 BFS 问题上犯了难。一点点分析,1. 每次都是空位置 0 做选择,移动相邻的上下左右的元素到 0 位置。

<!-- ```js
``` -->
4 changes: 2 additions & 2 deletions content/posts/algorithm/z-others/数组遍历指南.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,11 @@ while (count <= 25) {

```TS
// 数组大小为 5 * 5, 斜线对应索引为 [1, 4],所以外层for遍历斜线
for (let l = 1; l <= m - 1; ++l) {
for (let l = 1; l < m; ++l) {
// 接着分别确定 i 和 j坐标,这个需要找规律(数学归纳法嘛😂):
// 1. i 每次是减少 1 的, 区间为 [0,m-1-l]
// 2. j 不难发现线 l 与坐标 i,j 的关系: j = l + i
for (let i = 0; i <= m - 1 - l; ++i) {
for (let i = 0; i < m - l; ++i) { // l yueda i de youbianjie yue xiao
const j = l + i
console.log(Arr[i][j])
}
Expand Down
63 changes: 32 additions & 31 deletions content/posts/english/en.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: '我的英语学习之路'
date: 2023-01-01T10:30:18+08:00
lastmod: 2023-10-10
weight: 1
draft: true
---

> Learning English can make me happy~ -- 2023/01/01
Expand All @@ -25,19 +26,19 @@ weight: 1

{{<youtube -UuLXXQn5jA>}}

- 其实那些极个别的词根词缀我认为还是可以记一记的~
- 另外,个人觉得语境真的也很重要
- 其实那些极个别的词根词缀我认为还是可以记一记的~
- 另外,个人觉得语境真的也很重要

#### 推荐

- YouTube 地址:[EnglishClass101](https://www.youtube.com/@EnglishClass101/playlists)
- 手机 app :「墨墨背单词」,按照人的记忆曲线背单词,同时提供发音和例句~ 正在坚持打卡中 👊
- YouTube 地址:[EnglishClass101](https://www.youtube.com/@EnglishClass101/playlists)
- 手机 app :「墨墨背单词」,按照人的记忆曲线背单词,同时提供发音和例句~ 正在坚持打卡中 👊

### 美式发音:无脑信 Lisa 老师

#### 推荐

- YouTube 地址:[Accurate English](https://www.youtube.com/@AccurateEnglish)
- YouTube 地址:[Accurate English](https://www.youtube.com/@AccurateEnglish)

---

Expand All @@ -47,7 +48,7 @@ weight: 1

#### 推荐

- [EngVid](https://www.youtube.com/@EngVid/playlists),这里有初中高级语法完成视频教程,也有雅思托福听说写~。
- [EngVid](https://www.youtube.com/@EngVid/playlists),这里有初中高级语法完成视频教程,也有雅思托福听说写~。

#### 时态小总结

Expand All @@ -58,15 +59,15 @@ weight: 1
1. 动词形式:`past & present` 只需要修改 verb 的形态就好了,`feture` 需要在 verb 前加些料:`be going to``will``might`,就这么简单与 `aspect` 无关,**`but!`**,有时候 `present simple``present continuous` 也可以表示将来的意思,需要意会哦~ 比如: `what are you doing this weekend / class starts at 10:00`
2. 分清楚各个 `aspect``verb forms` 及意义

- `simple`,描述事实或习惯(重复的 actions/states) `past & verb & will+verb`
- `continuous`,描述某个时刻正在做(动作未完成或临时的) `was/were & am/is/are & will be + verb-ing`
- `perfect`,潜在意义里连接了两个时间点 `had & have(has) & will have + past`,我的感觉上是到终止日期完成(不一定是个具体的日期)
- `simple`,描述事实或习惯(重复的 actions/states) `past & verb & will+verb`
- `continuous`,描述某个时刻正在做(动作未完成或临时的) `was/were & am/is/are & will be + verb-ing`
- `perfect`,潜在意义里连接了两个时间点 `had & have(has) & will have + past`,我的感觉上是到终止日期完成(不一定是个具体的日期)

- `By yesterday, I had remembered 54 words` 从过去的一个点到另一个过去的点,译:已经....
- `I have remember 60 words now` 从过去一个点到现在,译:已经...
- `I will have remember 100 words by Sunday` 从现在到将来的一个点,译:将会/会...
- `By yesterday, I had remembered 54 words` 从过去的一个点到另一个过去的点,译:已经....
- `I have remember 60 words now` 从过去一个点到现在,译:已经...
- `I will have remember 100 words by Sunday` 从现在到将来的一个点,译:将会/会...

- `perfect continus`,在 perfect 的基础上强调动作未完成或临时的`~ `had & have(has) & will have + been + verb-ing`,有时候可以被 perfect 取代~
- `perfect continus`,在 perfect 的基础上强调动作未完成或临时的`~ `had & have(has) & will have + been + verb-ing`,有时候可以被 perfect 取代~

{{< admonition note >}}
以上是我自己学习后的感悟就记录了下来,其实看文字没啥卵用,重点是一定要理解了
Expand All @@ -76,32 +77,32 @@ weight: 1

这三个是比较常用的 `情态动词 + have + 过去分词` 组合形式,需要理解含义,多说。

- `would have`,等价于中文的 `要是...,就/就会...`**`就/就会`**
- `If I had studied harder, I would have gone to a better university`
- `could have`,等价于中文的 `就可以.../本可以.../有可能.../(本)应该.../本来...`
- `If I had more time, I could have finished it/ He could have won it if he hadn't...`
- `They could have mixed up the date/ I could have lost my keys` _这里表猜测_
- `You could have told me sooner` _这里表批评_
- `We were really late, and we could have missed our plane, but luckily we just made it` _表示幸运地避免了坏情况_
- `should have`,等价于中文的 `(本)应该...`, 带有点批评的意思,有时候也表示期望的事情没有发生
- `You should have call me like you promised` 表示批评
- `They should been here by now` 表示期待的事情未发生
- `would have`,等价于中文的 `要是...,就/就会...`**`就/就会`**
- `If I had studied harder, I would have gone to a better university`
- `could have`,等价于中文的 `就可以.../本可以.../有可能.../(本)应该.../本来...`
- `If I had more time, I could have finished it/ He could have won it if he hadn't...`
- `They could have mixed up the date/ I could have lost my keys` _这里表猜测_
- `You could have told me sooner` _这里表批评_
- `We were really late, and we could have missed our plane, but luckily we just made it` _表示幸运地避免了坏情况_
- `should have`,等价于中文的 `(本)应该...`, 带有点批评的意思,有时候也表示期望的事情没有发生
- `You should have call me like you promised` 表示批评
- `They should been here by now` 表示期待的事情未发生

---

## 其他推荐

- YouTuBe 地址:[LearnEnglishWithTVSeries](https://www.youtube.com/@LearnEnglishWithTVSeries/playlists),看美剧学英语
- 手机 app:「**voscreen**」,跟随电影配音练听力口语,很方便。PS: 需要有美区 appleID
- YouTuBe 地址:[LearnEnglishWithTVSeries](https://www.youtube.com/@LearnEnglishWithTVSeries/playlists),看美剧学英语
- 手机 app:「**voscreen**」,跟随电影配音练听力口语,很方便。PS: 需要有美区 appleID

## 英语杂志推荐

- https://www.economist.com/
- https://www.vanityfair.com/
- https://www.rd.com/
- https://www.newyorker.com/
- https://www.nationalgeographic.com/
- https://www.lonelyplanet.com/
- https://www.economist.com/
- https://www.vanityfair.com/
- https://www.rd.com/
- https://www.newyorker.com/
- https://www.nationalgeographic.com/
- https://www.lonelyplanet.com/

## 最最最重要的

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tags: []
series: [java]
categories: [study notes]
weight: 1
draft: true
---

如今只会前端让我感到处处受制于人,很多自己的想法难以实现,严重依赖于后端,为了改变现状,我决定今年另一个小目标就是掌握 java,以及它的相关技术栈,不折腾一下,做什么程序员?Let's go!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tags: []
series: [java]
categories: [study notes]
weight: 10
draft: true
---

前端学过 TypeScript,对泛型是一定的理解,来看看 java 的泛型吧。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ tags: []
series: [java]
categories: [study notes]
weight: 11
draft: true
---

## JFrame & JPanel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ lastmod:
series: [java]
categories: [study notes]
weight: 12
draft: true
---

## IO 流
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ lastmod:
series: [java]
categories: [study notes]
weight: 13
draft: true
---

作为前端开发,对网络这块大体还是比较熟悉的,如需要深度学习网络,可以后续深度学习~
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ lastmod:
series: [java]
categories: [study notes]
weight: 14
draft: true
---

## 场景
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tags: []
series: [java]
categories: [study notes]
weight: 2
draft: true
---

## JAVA 基本数据类型
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tags: []
series: [java]
categories: [study notes]
weight: 3
draft: true
---

面向对象编程三大特性:`封装、继承和多态`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tags: []
series: [java]
categories: [study notes]
weight: 4
draft: true
---

## Object 类
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tags: []
series: [java]
categories: [study notes]
weight: 5
draft: true
---

## 接口
Expand Down
Loading

0 comments on commit e9a92c5

Please sign in to comment.