Skip to content

Commit d1072e5

Browse files
feat: update
1 parent 3e08cf0 commit d1072e5

File tree

11 files changed

+823
-364
lines changed

11 files changed

+823
-364
lines changed

docs/.vuepress/config.js

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
function GeneratorMenu(pathPrefix, pathnameList) {
55
let result = [];
6-
for(let i = 0; i < pathnameList.length; i++) {
6+
for (let i = 0; i < pathnameList.length; i++) {
77
result[i] = [`${pathPrefix}${pathnameList[i]}`, pathnameList[i]];
88
}
99
return result;
@@ -77,6 +77,7 @@ const TreeList = GeneratorMenu('/algorithm/树/', [
7777
'翻转二叉树',
7878
'另一个树的子树',
7979
'验证二叉搜索树',
80+
'二叉树的最大深度',
8081
'二叉树的最小深度',
8182
'平衡二叉树',
8283
'将有序数组转换为二叉搜索树',
@@ -87,32 +88,26 @@ const TreeList = GeneratorMenu('/algorithm/树/', [
8788

8889
module.exports = {
8990
base: '/blog/',
90-
title: '前端学习总结',
91+
title: '前端学习总结',
9192
description: '前端学习总结',
92-
head: [
93-
['link', { rel: 'icon', href: 'https://cdn.wangyaxing.cn/icon-128x128.png' }],
94-
],
93+
head: [['link', { rel: 'icon', href: 'https://cdn.wangyaxing.cn/icon-128x128.png' }]],
9594
themeConfig: {
9695
sidebarDepth: 2,
9796
lastUpdated: 'Last Updated',
9897
nav: [
99-
{
100-
text: '首页',
101-
link: '/'
98+
{
99+
text: '首页',
100+
link: '/',
102101
},
103-
{
102+
{
104103
text: '算法',
105-
link: '/algorithm/'
104+
link: '/algorithm/',
106105
},
107-
{ text: '手写代码',
108-
link: '/jsCode/'
109-
},
110-
{ text: '面试题',
111-
link: '/interview/'
112-
},
113-
{
106+
{ text: '手写代码', link: '/jsCode/' },
107+
{ text: '面试题', link: '/interview/' },
108+
{
114109
text: '100天',
115-
link: '/100day/'
110+
link: '/100day/',
116111
},
117112
{ text: 'Github', link: 'https://github.com/funnycoderstar/blog' },
118113
],
@@ -143,7 +138,7 @@ module.exports = {
143138
['/algorithm/数学/中位数', '中位数'],
144139
['/algorithm/数学/只出现一次的数字', '只出现一次的数字'],
145140
['/algorithm/数学/有效的三角形个数', '有效的三角形个数'],
146-
]
141+
],
147142
},
148143
{
149144
title: '动态规划',
@@ -161,7 +156,7 @@ module.exports = {
161156
['/algorithm/动态规划/打家劫舍', '打家劫舍'],
162157
['/algorithm/动态规划/打家劫舍II', '打家劫舍 II'],
163158
['/algorithm/动态规划/打家劫舍III', '打家劫舍 III'],
164-
]
159+
],
165160
},
166161
],
167162
'/jsCode/': [
@@ -196,10 +191,13 @@ module.exports = {
196191
['/interview/CSS/实现固定宽高比的div', '实现固定宽高比的div'],
197192
['/interview/CSS/css解析规则', 'css解析规则'],
198193
['/interview/CSS/CSS选择器', 'CSS选择器'],
199-
['/interview/CSS/display:none和visibility:hidden的区别', 'display: none和 visibility:hidden的区别'],
194+
[
195+
'/interview/CSS/display:none和visibility:hidden的区别',
196+
'display: none和 visibility:hidden的区别',
197+
],
200198
['/interview/CSS/flex.md', 'flex:1'],
201199
['/interview/CSS/常见CSS布局的实现', '常见CSS布局的实现'],
202-
]
200+
],
203201
},
204202
{
205203
title: 'JavaScript',
@@ -218,7 +216,7 @@ module.exports = {
218216
['/interview/React/生命周期介绍', 'React生命周期'],
219217
['/interview/React/合成事件', 'React合成事件'],
220218
['/interview/React/自定义hook', '自定义hook'],
221-
]
219+
],
222220
},
223221
{
224222
title: 'HTTP',
@@ -229,9 +227,12 @@ module.exports = {
229227
['/interview/HTTP/三次握手,四次挥手', '三次握手,四次挥手'],
230228
['/interview/HTTP/HTTP状态码', 'HTTP状态码'],
231229
['/interview/HTTP/HTTP请求方法', 'HTTP请求方法'],
232-
['/interview/HTTP/一个url到页面展示的完整流程', '一个url到页面展示的完整流程'],
230+
[
231+
'/interview/HTTP/一个url到页面展示的完整流程',
232+
'一个url到页面展示的完整流程',
233+
],
233234
['/interview/HTTP/TCP和UDP', 'TCP和UDP'],
234-
]
235+
],
235236
},
236237
{
237238
title: 'Webpack',
@@ -241,7 +242,7 @@ module.exports = {
241242
['/interview/Webpack/webpack热更新原理', 'webpack热更新原理'],
242243
['/interview/Webpack/优化构建速度', '优化构建速度'],
243244
['/interview/Webpack/优化代码体积', '优化代码体积'],
244-
]
245+
],
245246
},
246247
{
247248
title: '笔试题',
@@ -257,31 +258,30 @@ module.exports = {
257258
['/interview/笔试题/4', '笔试题2'],
258259
['/interview/笔试题/5', '笔试题3'],
259260
['/interview/笔试题/6', '笔试题4'],
260-
261-
]
261+
],
262262
},
263263
{
264264
title: '面经分享',
265265
collapsable: true,
266266
children: [
267267
['/interview/面经/2017', '2017年面试总结'],
268268
['/interview/面经/2020-面试', '2020年面试总结'],
269-
]
269+
],
270270
},
271271
],
272272
'/100day/': [
273273
['/100day/', '100天计划专题'],
274274
{
275275
title: '文章',
276276
collapsable: true,
277-
children: articles100List
277+
children: articles100List,
278278
},
279279
{
280280
title: '算法题',
281281
collapsable: true,
282-
children: algorithm100List
282+
children: algorithm100List,
283283
},
284284
],
285-
}
286-
}
287-
}
285+
},
286+
},
287+
};

docs/100day/README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,14 @@
4444

4545
---
4646
- Day31:[Web安全之CSRF](../interview/HTTP/Web安全之CSRF.md)
47+
- Day32:[HTTPS是如何保证安全的]()
48+
- Day33:[JavaScript代码是如何被执行的]()
49+
- Day34:[V8内存管理及垃圾回收机制]()
50+
- Day35:[深入理解JavaScript执行上下文]()
51+
- Day36:[[深入理解JavaScript作用域]()
52+
- Day37:[深入理解JavaScript闭包之什么是闭包]()
4753
- 同源策略及跨域的几种方法
4854
- TCP和UDP
49-
- HTTPS
5055

5156
#### 算法题
5257
- [买卖股票的最佳时机](./算法题/买卖股票的最佳时机.md)
@@ -90,4 +95,5 @@
9095
- Day31:[打家劫舍II](../algorithm/动态规划/打家劫舍II.md)
9196
- Day33: [打家劫舍III](../algorithm/动态规划/打家劫舍III.md)
9297
- Day35: [二叉搜索树的最近公共祖先](../algorithm/树/二叉搜索树的最近公共祖先.md)
93-
- Day35: 买卖股票的最佳时机III
98+
- Day35: [三数之和]()
99+
- Day36: [更接近的三数之和]()
Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
JavaScript实现LeetCode第236题: 二叉树的最近公共祖先
1+
JavaScript 实现 LeetCode 第 236 题: 二叉树的最近公共祖先
22

33
## 题目描述
44

@@ -14,38 +14,61 @@ JavaScript实现LeetCode第236题: 二叉树的最近公共祖先
1414
5 1
1515
/ \ / \
1616
6 2 0 8
17-
/ \
18-
7 4
17+
/ \
18+
7 4
1919
```
20-
 
2120

2221
示例 1:
22+
2323
```js
2424
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
2525
输出: 3
2626
解释: 节点 5 和节点 1 的最近公共祖先是节点 3
2727

2828
```
29-
示例 2:
29+
30+
示例  2:
31+
3032
```js
3133
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
3234
输出: 5
3335
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。
3436

3537
```
38+
3639
说明:
37-
- 所有节点的值都是唯一的。
38-
- p、q 为不同节点且均存在于给定的二叉树中
40+
41+
- 所有节点的值都是唯一的。
42+
- p、q 为不同节点且均存在于给定的二叉树中
43+
3944
## 解题方法
40-
使用递归:
4145

42-
fx 表示 x 节点的子树中是否包含 p 节点或 q 节点,如果包含为 true,否则为 false。那么符合条件的最近公共祖先 x 一定满足如下条件:
43-
(f(lson) && f(rson)) || ((x === p || x === q) && (f(lson) || f(rson)))
46+
思考一些细节:
47+
48+
1. 函数是干嘛的
49+
2. 函数参数中的变量是什么
50+
3. 得到函数的递归结果,应该干什么
4451

45-
1. 左子树和右子树均包含 p节点或q节点,如果左子树包含的是 p 节点,那么右子树只能包含 q节点。反之亦然,因为 p 节点和 q 节点都是不同且唯一的节点,因此如果满足这个判断条件即可说明 x 就是我们要找的最近公共祖先
46-
2. x 恰好是 p 节点或 q 节点且 它的左子树或右子树有一个包含了另一个节点的情况,因此满足满足这个条件也可以说明 xx 就是我们要找的最近公共祖先。
52+
### 1.函数是干嘛的
4753

48-
我们是自底向上从叶子节点开始更新的,所以在所有满足条件的公共祖先中一定是深度最大的祖先先被访问到,且由于 fx 本身的定义很巧妙,在找到最近公共祖先 x 以后,fx 按定义被设置为 true ,即假定了这个子树中只有一个 p 节点或 q 节点,因此其他公共祖先不会再被判断为符合条件。
54+
`lowestCommonAncestor` 函数定义:给该函数传入 3 个参数,root, p, q,它会返回一个节点。
55+
56+
情况 1,如果 p 和 q 都在以 root 为根的树中,函数返回的就是 p 和 q 的最近公共祖先节点
57+
情况 2,如果 p 和 q 都不在以 root 为根的树中,就应该返回 null
58+
情况 3,如果 p 和 q 只有一个在以 root 为根的树中,就应该返回这个节点
59+
60+
### 2.函数参数中的变量是什么
61+
62+
函数参数中变量是 root, `lowestCommonAncestor(root)` 会递归调用 `root.left``root.right``p``q`是不会变化的
63+
64+
### 3.得到函数的递归结果,应该干什么
65+
66+
- 如果 root 为空,肯定要返回 null
67+
- 如果 root 本身就是 p 或者 q,比如说 root 是 p 节点,如果 q 存在于以 root 为根的树中,显然 root 就是最近公共祖先
68+
- 对递归结果的 left 和 right 进行处理
69+
- 情况 1,如果 p 和 q 都在以 root 为根的树中,函数返回的就是 p 和 q 的最近公共祖先节点
70+
- 情况 2,如果 p 和 q 都不在以 root 为根的树中,就应该返回 null
71+
- 情况 3,如果 p 和 q 只有一个在以 root 为根的树中,就应该返回这个节点
4972

5073
```js
5174
/**
@@ -62,22 +85,28 @@ fx 表示 x 节点的子树中是否包含 p 节点或 q 节点,如果包含
6285
* @return {TreeNode}
6386
*/
6487
var lowestCommonAncestor = function(root, p, q) {
65-
let result = null;
66-
function dfs(root, p, q) {
67-
if(root === null) {
68-
return false;
69-
}
70-
const lson = dfs(root.left, p, q);
71-
const rson = dfs(root.right, p, q);
72-
73-
if((lson && rson) || (root.val === p.val || root.val === q.val) && (lson || rson)) {
74-
result = root;
75-
}
76-
return lson || rson || (root.val === p.val || root.val === q.val);
88+
if (root === null) {
89+
return null;
7790
}
78-
dfs(root, p, q);
79-
return result;
91+
// root本身就是p或者q,返回 root节点
92+
if (root === p || root === q) {
93+
return root;
94+
}
95+
// 后序遍历,从下往上遍历,好比从p和q出发往上走,第一次相交的节点就是root,就是最近的公共祖先
96+
const left = lowestCommonAncestor(root.left, p, q);
97+
const right = lowestCommonAncestor(root.right, p, q);
98+
// 如果 p 和 q 都在以root为根的树中,left和 right不是返回null,就是返回root
99+
if (left !== null && right !== null) {
100+
return root;
101+
}
102+
// 如果 p 和 q 都不在以root为根的树中,直接返回null
103+
if (left === null && right === null) {
104+
return null;
105+
}
106+
// 如果 p和q只有一个存在于root为根的树中
107+
return left === null ? right : left;
80108
};
81109
```
82-
- 时间复杂度: O(N)。其中 N 是二叉树的节点数。二叉树的所有节点有且只会被访问一次,因此时间复杂度为 O(N)。
83-
- 空间复杂度:O(N) ,其中 N 是二叉树的节点数。递归调用的栈深度取决于二叉树的高度,二叉树最坏情况下为一条链,此时高度为 N,因此空间复杂度为 O(N)。
110+
111+
- 时间复杂度: O(N)。其中 N 是二叉树的节点数。二叉树的所有节点有且只会被访问一次,因此时间复杂度为 O(N)。
112+
- 空间复杂度:O(N) ,其中 N 是二叉树的节点数。递归调用的栈深度取决于二叉树的高度,二叉树最坏情况下为一条链,此时高度为 N,因此空间复杂度为 O(N)。

docs/interview/HTTP/HTTPS.md

Lines changed: 0 additions & 57 deletions
This file was deleted.

0 commit comments

Comments
 (0)