Skip to content

Commit 9ee5312

Browse files
committed
保存作业
1 parent 47f14c2 commit 9ee5312

2 files changed

Lines changed: 235 additions & 1 deletion

File tree

Week07/NOTE.md

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,141 @@
1111
3. 每个节点的所有子节点路径代表的字符都不相同
1212
* 核心思想
1313
1. 核心思想:空间换时间
14-
2. 利用字符串的公共前缀来降低查询的开销以达到提高效率的目的
14+
2. 利用字符串的公共前缀来降低查询的开销以达到提高效率的目的
15+
* 字典树的实现(js实现)
16+
```
17+
var TrieNode = function () {
18+
this.next = {}
19+
this.isEnd = false
20+
}
21+
var Trie = function() {
22+
this.root = new TrieNode()
23+
};
24+
25+
/**
26+
* Inserts a word into the trie.
27+
* @param {string} word
28+
* @return {void}
29+
*/
30+
Trie.prototype.insert = function(word) {
31+
if (!word) {
32+
return false
33+
}
34+
35+
let node = this.root
36+
for(let i = 0; i < word.length; i++) {
37+
if (!node.next[word[i]]) {
38+
node.next[word[i]] = new TrieNode()
39+
}
40+
node = node.next[word[i]]
41+
}
42+
node.isEnd = true
43+
return true
44+
};
45+
46+
/**
47+
* Returns if the word is in the trie.
48+
* @param {string} word
49+
* @return {boolean}
50+
*/
51+
Trie.prototype.search = function(word) {
52+
if (!word) {
53+
return false
54+
}
55+
let node = this.root
56+
for(let i = 0; i < word.length; i++) {
57+
if (node.next[word[i]]) {
58+
node = node.next[word[i]]
59+
} else {
60+
return false
61+
}
62+
}
63+
return node.isEnd
64+
};
65+
66+
/**
67+
* Returns if there is any word in the trie that starts with the given prefix.
68+
* @param {string} prefix
69+
* @return {boolean}
70+
*/
71+
Trie.prototype.startsWith = function(prefix) {
72+
if (!prefix) {
73+
return false
74+
}
75+
let node = this.root
76+
for(let i = 0; i < prefix.length; i++) {
77+
if (node.next[prefix[i]]) {
78+
node = node.next[prefix[i]]
79+
} else {
80+
return false
81+
}
82+
}
83+
return true
84+
};
85+
```
86+
87+
### 并查集
88+
* 适用场景
89+
* 组团,配对问题
90+
* Group or not?
91+
* 基本操作
92+
1. makeSet(s)
93+
2. unionSet(x, y)
94+
3. find(x)
95+
* 代码模版 js实现
96+
```
97+
class UnionFind {
98+
constructor(n = 0) {
99+
this.count = n
100+
this.parent = []
101+
for(let i = 0; i < n; i++) {
102+
this.parent[i] = i
103+
}
104+
}
105+
find(p) {
106+
while(p != this.parent[p]) {
107+
this.parent[p] = this.parent[this.parent[p]]
108+
p = parent[p]
109+
}
110+
return p;
111+
}
112+
union(p, q) {
113+
let rootP = this.find(p)
114+
let rootQ = this.find(q)
115+
if(rootP === rootQ) {
116+
return
117+
}
118+
parent[rootP] = rootQ
119+
count --
120+
}
121+
}
122+
```
123+
124+
## 高级搜索
125+
* 剪枝
126+
* 双向BFS
127+
```
128+
```
129+
* 启发式搜索 A*
130+
* 估价函数h(n):用来评估哪些节点最有希望的是一个我们要找的节点,h(n)会返回一个非负实数,也可以认为是从节点n到目标路径的估计成本
131+
132+
## AVL树和红黑树的
133+
### AVL树
134+
* 平衡的二叉搜索树
135+
* 平衡因子 Balance Factor:它的左子树的高度减去它的右子树的高度(有时候相反)
136+
balance factor = { -1, 0, 1}
137+
* 通过旋转操作来进行平衡(四种)
138+
1. 左旋
139+
2. 右旋
140+
3. 左右旋
141+
4. 右左旋
142+
* 不足:节点需要存储额外信息,且调整次数频繁
143+
144+
## 红黑树 Red-black Tree
145+
* 近似平衡的二叉搜索树,它能够确保任何一个节点的左右子树的高度差小于两倍。具体来说满足以下条件的二叉搜索树
146+
1. 每个节点要么是红色要么是黑色
147+
2. 根节点是黑色
148+
3. 每个叶子节点(NIL节点,空节点)是黑色
149+
4. 不能有相邻的两个红色节点
150+
5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点
151+
*关键特性:从根到叶子的最长的可能路径不多于最短的可能路径的两倍长*
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/**
2+
* @param {character[][]} board
3+
* @param {string[]} words
4+
* @return {string[]}
5+
*/
6+
// Trie 数据结构实现
7+
var TrieNode = function() {
8+
this.next = {}
9+
this.isEnd = false
10+
}
11+
var Trie = function() {
12+
this.root = new TrieNode()
13+
}
14+
Trie.prototype.insert = function(word) {
15+
if(!word) {
16+
return false
17+
}
18+
let node = this.root
19+
for(let i = 0; i < word.length; i++) {
20+
if (!node.next[word[i]]) {
21+
node.next[word[i]] = new TrieNode()
22+
}
23+
node = node.next[word[i]]
24+
}
25+
node.isEnd = true
26+
return true
27+
}
28+
Trie.prototype.search = function(word) {
29+
if(!word) {
30+
return false
31+
}
32+
let node = this.root
33+
for(let i = 0; i < word.length; i++) {
34+
if(node.next[word[i]]) {
35+
node = node.next[word[i]]
36+
} else {
37+
return false
38+
}
39+
}
40+
return node.isEnd
41+
}
42+
Trie.prototype.searchPrefix = function(prefix) {
43+
if(!prefix) {
44+
return false
45+
}
46+
let node = this.root
47+
for(let i = 0; i < prefix.length; i++) {
48+
if (node.next[prefix[i]]) {
49+
node = node.next[prefix[i]]
50+
} else {
51+
return false
52+
}
53+
}
54+
return true
55+
}
56+
57+
58+
var findWords = function(board, words) {
59+
var trie = new Trie()
60+
// 初始化Trie树
61+
for(let i = 0; i < words.length; i++) {
62+
trie.insert(words[i])
63+
}
64+
// 初始化变量
65+
const [m, n] = [board.length, board[0].length]
66+
// 四联通
67+
const dx = [-1, 1, 0, 0]
68+
const dy = [0, 0, -1, 1]
69+
const res = []
70+
var dfs = (i, j, curStr) => {
71+
const restore = board[i][j]
72+
curStr += restore
73+
74+
if (trie.search(curStr) && res.indexOf(curStr) === -1) {
75+
res.push(curStr)
76+
}
77+
if (!trie.searchPrefix(curStr)) {
78+
return
79+
}
80+
81+
board[i][j] = '@'
82+
for(let k = 0; k < 4; k ++) {
83+
const [x, y] = [i + dx[k], j + dy[k]]
84+
if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] !== '@') {
85+
dfs(x,y, curStr)
86+
}
87+
}
88+
board[i][j] = restore
89+
}
90+
91+
for (let i = 0; i < m; i++) {
92+
for(let j = 0; j < n; j ++) {
93+
dfs(i, j, '')
94+
}
95+
}
96+
return res
97+
};

0 commit comments

Comments
 (0)