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

Commit 6d0a559

Browse files
Merge pull request SharingSource#29 from SharingSource/ac_oier
✨feat: Add 剑指 Offer 37、297
2 parents 0970b98 + 7c40236 commit 6d0a559

File tree

4 files changed

+267
-0
lines changed

4 files changed

+267
-0
lines changed

‎Index/BFS.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
| 题目 | 题解 | 难度 | 推荐指数 |
22
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
33
| [90. 子集 II](https://leetcode-cn.com/problems/subsets-ii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/subsets-ii/solution/gong-shui-san-xie-yi-ti-shuang-jie-hui-s-g77q/) | 中等 | 🤩🤩🤩🤩 |
4+
| [297. 二叉树的序列化与反序列化](https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/solution/gong-shui-san-xie-er-cha-shu-de-xu-lie-h-n89a/) | 困难 | |
45
| [403. 青蛙过河](https://leetcode-cn.com/problems/frog-jump/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/frog-jump/solution/gong-shui-san-xie-yi-ti-duo-jie-jiang-di-74fw/) | 困难 | 🤩🤩🤩🤩 |
56
| [690. 员工的重要性](https://leetcode-cn.com/problems/employee-importance/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/employee-importance/solution/gong-shui-san-xie-yi-ti-shuang-jie-di-gu-s79x/) | 简单 | 🤩🤩🤩 |
67
| [778. 水位上升的泳池中游泳](https://leetcode-cn.com/problems/swim-in-rising-water/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/swim-in-rising-water/solution/gong-shui-san-xie-yi-ti-shuang-jie-krusk-7c6o/) | 困难 | 🤩🤩🤩 |

‎Index/二叉树.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
| 题目 | 题解 | 难度 | 推荐指数 |
2+
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
3+
| [297. 二叉树的序列化与反序列化](https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/solution/gong-shui-san-xie-er-cha-shu-de-xu-lie-h-n89a/) | 困难 | 🤩🤩🤩🤩🤩 |
4+
| [783. 二叉搜索树节点最小距离](https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/solution/gong-shui-san-xie-yi-ti-san-jie-shu-de-s-7r17/) | 简单 | 🤩🤩🤩 |
5+
| [938. 二叉搜索树的范围和](https://leetcode-cn.com/problems/range-sum-of-bst/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/range-sum-of-bst/solution/gong-shui-san-xie-yi-ti-shuang-jie-di-gu-q2fo/) | 简单 | 🤩🤩🤩 |
6+
| [993. 二叉树的堂兄弟节点](https://leetcode-cn.com/problems/cousins-in-binary-tree/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/cousins-in-binary-tree/solution/gong-shui-san-xie-shu-de-sou-suo-dfs-bfs-b200/) | 简单 | 🤩🤩 |
7+
| [剑指 Offer 37. 序列化二叉树](https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/solution/gong-shui-san-xie-er-cha-shu-de-xu-lie-h-n89a/) | 困难 | 🤩🤩🤩🤩🤩 |
8+
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[297. 二叉树的序列化与反序列化](https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/solution/gong-shui-san-xie-er-cha-shu-de-xu-lie-h-n89a/)** ,难度为 **困难**
4+
5+
Tag : 「二叉树」、「层序遍历」
6+
7+
8+
9+
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
10+
11+
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
12+
13+
提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
14+
15+
示例 1:
16+
![](https://assets.leetcode.com/uploads/2020/09/15/serdeser.jpg)
17+
```
18+
输入:root = [1,2,3,null,null,4,5]
19+
输出:[1,2,3,null,null,4,5]
20+
```
21+
示例 2:
22+
```
23+
输入:root = []
24+
输出:[]
25+
```
26+
示例 3:
27+
```
28+
输入:root = [1]
29+
输出:[1]
30+
```
31+
示例 4:
32+
```
33+
输入:root = [1,2]
34+
输出:[1,2]
35+
```
36+
37+
提示:
38+
* 树中结点数在范围 $[0, 10^4]$ 内
39+
* -1000 <= Node.val <= 1000
40+
41+
---
42+
43+
### 基本思路
44+
45+
无论使用何种「遍历方式」进行二叉树存储,为了方便,我们都需要对空节点有所表示。
46+
47+
其实题目本身的样例就给我们提供了很好的思路:**使用层序遍历的方式进行存储,对于某个叶子节点的空节点进行存储,同时确保不递归存储空节点对应的子节点。**
48+
49+
---
50+
51+
### 层序遍历
52+
53+
根据节点值的数据范围 `-1000 <= Node.val <= 1000`(我是在 [297. 二叉树的序列化与反序列化](https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/) 看的,你也可以不使用数字,使用某个特殊字符进行表示,只要能在反序列时有所区分即可),我们可以建立占位节点 `emptyNode` 用来代指空节点(`emptyNode.val = INF`)。
54+
55+
序列化:先特判掉空树的情况,之后就是常规的层序遍历逻辑:
56+
57+
1. 起始时,将 `root` 节点入队;
58+
2. 从队列中取出节点,检查节点是否有左/右节点:
59+
* 如果有的话,将值追加序列化字符中(注意使用分隔符),并将节点入队;
60+
* 如果没有,检查当前节点是否为 `emptyNode` 节点,如果不是 `emptyNode` 说明是常规的叶子节点,需要将其对应的空节点进行存储,即将 `emptyNode` 入队;
61+
3. 循环流程 2ドル,ドル直到整个队列为空。
62+
63+
反序列:同理,怎么「序列化」就怎么进行「反序列」即可:
64+
65+
1. 起始时,构造出 `root` 并入队;
66+
2. 每次从队列取出元素时,同时从序列化字符中截取两个值(对应左右节点),检查是否为 `INF`,若不为 `INF` 则构建对应节点;
67+
3. 循环流程 2ドル,ドル直到整个序列化字符串被处理完(注意跳过最后一位分隔符)。
68+
69+
代码:
70+
```Java []
71+
public class Codec {
72+
int INF = -2000;
73+
TreeNode emptyNode = new TreeNode(INF);
74+
public String serialize(TreeNode root) {
75+
if (root == null) return "";
76+
77+
StringBuilder sb = new StringBuilder();
78+
Deque<TreeNode> d = new ArrayDeque<>();
79+
d.addLast(root);
80+
while (!d.isEmpty()) {
81+
TreeNode poll = d.pollFirst();
82+
sb.append(poll.val + "_");
83+
if (!poll.equals(emptyNode)) {
84+
d.addLast(poll.left != null ? poll.left : emptyNode);
85+
d.addLast(poll.right != null ? poll.right : emptyNode);
86+
}
87+
}
88+
return sb.toString();
89+
}
90+
91+
public TreeNode deserialize(String data) {
92+
if (data.equals("")) return null;
93+
94+
String[] ss = data.split("_");
95+
int n = ss.length;
96+
TreeNode root = new TreeNode(Integer.parseInt(ss[0]));
97+
Deque<TreeNode> d = new ArrayDeque<>();
98+
d.addLast(root);
99+
for (int i = 1; i < n - 1; i += 2) {
100+
TreeNode poll = d.pollFirst();
101+
int a = Integer.parseInt(ss[i]), b = Integer.parseInt(ss[i + 1]);
102+
if (a != INF) {
103+
poll.left = new TreeNode(a);
104+
d.addLast(poll.left);
105+
}
106+
if (b != INF) {
107+
poll.right = new TreeNode(b);
108+
d.addLast(poll.right);
109+
}
110+
}
111+
return root;
112+
}
113+
}
114+
```
115+
* 时间复杂度:$O(n)$
116+
* 空间复杂度:$O(n)$
117+
118+
---
119+
120+
### 最后
121+
122+
这是我们「刷穿 LeetCode」系列文章的第 `No.297` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先将所有不带锁的题目刷完。
123+
124+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
125+
126+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
127+
128+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
129+
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[剑指 Offer 37. 序列化二叉树](https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/solution/gong-shui-san-xie-er-cha-shu-de-xu-lie-h-n89a/)** ,难度为 **困难**
4+
5+
Tag : 「二叉树」、「层序遍历」
6+
7+
8+
9+
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
10+
11+
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
12+
13+
提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
14+
15+
示例 1:
16+
![](https://assets.leetcode.com/uploads/2020/09/15/serdeser.jpg)
17+
```
18+
输入:root = [1,2,3,null,null,4,5]
19+
输出:[1,2,3,null,null,4,5]
20+
```
21+
示例 2:
22+
```
23+
输入:root = []
24+
输出:[]
25+
```
26+
示例 3:
27+
```
28+
输入:root = [1]
29+
输出:[1]
30+
```
31+
示例 4:
32+
```
33+
输入:root = [1,2]
34+
输出:[1,2]
35+
```
36+
37+
提示:
38+
* 树中结点数在范围 $[0, 10^4]$ 内
39+
* -1000 <= Node.val <= 1000
40+
41+
---
42+
43+
### 基本思路
44+
45+
无论使用何种「遍历方式」进行二叉树存储,为了方便,我们都需要对空节点有所表示。
46+
47+
其实题目本身的样例就给我们提供了很好的思路:**使用层序遍历的方式进行存储,对于某个叶子节点的空节点进行存储,同时确保不递归存储空节点对应的子节点。**
48+
49+
---
50+
51+
### 层序遍历
52+
53+
根据节点值的数据范围 `-1000 <= Node.val <= 1000`(我是在 [297. 二叉树的序列化与反序列化](https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/) 看的,你也可以不使用数字,使用某个特殊字符进行表示,只要能在反序列时有所区分即可),我们可以建立占位节点 `emptyNode` 用来代指空节点(`emptyNode.val = INF`)。
54+
55+
序列化:先特判掉空树的情况,之后就是常规的层序遍历逻辑:
56+
57+
1. 起始时,将 `root` 节点入队;
58+
2. 从队列中取出节点,检查节点是否有左/右节点:
59+
* 如果有的话,将值追加序列化字符中(注意使用分隔符),并将节点入队;
60+
* 如果没有,检查当前节点是否为 `emptyNode` 节点,如果不是 `emptyNode` 说明是常规的叶子节点,需要将其对应的空节点进行存储,即将 `emptyNode` 入队;
61+
3. 循环流程 2ドル,ドル直到整个队列为空。
62+
63+
反序列:同理,怎么「序列化」就怎么进行「反序列」即可:
64+
65+
1. 起始时,构造出 `root` 并入队;
66+
2. 每次从队列取出元素时,同时从序列化字符中截取两个值(对应左右节点),检查是否为 `INF`,若不为 `INF` 则构建对应节点;
67+
3. 循环流程 2ドル,ドル直到整个序列化字符串被处理完(注意跳过最后一位分隔符)。
68+
69+
代码:
70+
```Java []
71+
public class Codec {
72+
int INF = -2000;
73+
TreeNode emptyNode = new TreeNode(INF);
74+
public String serialize(TreeNode root) {
75+
if (root == null) return "";
76+
77+
StringBuilder sb = new StringBuilder();
78+
Deque<TreeNode> d = new ArrayDeque<>();
79+
d.addLast(root);
80+
while (!d.isEmpty()) {
81+
TreeNode poll = d.pollFirst();
82+
sb.append(poll.val + "_");
83+
if (!poll.equals(emptyNode)) {
84+
d.addLast(poll.left != null ? poll.left : emptyNode);
85+
d.addLast(poll.right != null ? poll.right : emptyNode);
86+
}
87+
}
88+
return sb.toString();
89+
}
90+
91+
public TreeNode deserialize(String data) {
92+
if (data.equals("")) return null;
93+
94+
String[] ss = data.split("_");
95+
int n = ss.length;
96+
TreeNode root = new TreeNode(Integer.parseInt(ss[0]));
97+
Deque<TreeNode> d = new ArrayDeque<>();
98+
d.addLast(root);
99+
for (int i = 1; i < n - 1; i += 2) {
100+
TreeNode poll = d.pollFirst();
101+
int a = Integer.parseInt(ss[i]), b = Integer.parseInt(ss[i + 1]);
102+
if (a != INF) {
103+
poll.left = new TreeNode(a);
104+
d.addLast(poll.left);
105+
}
106+
if (b != INF) {
107+
poll.right = new TreeNode(b);
108+
d.addLast(poll.right);
109+
}
110+
}
111+
return root;
112+
}
113+
}
114+
```
115+
* 时间复杂度:$O(n)$
116+
* 空间复杂度:$O(n)$
117+
118+
---
119+
120+
### 最后
121+
122+
这是我们「刷穿 LeetCode」系列文章的第 `剑指 Offer 37` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先将所有不带锁的题目刷完。
123+
124+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
125+
126+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
127+
128+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
129+

0 commit comments

Comments
(0)

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