diff --git a/README.md b/README.md
index efb19dc3..6d92a5d5 100644
--- a/README.md
+++ b/README.md
@@ -121,6 +121,8 @@
* [二叉树:搜索树的公共祖先问题](https://mp.weixin.qq.com/s/Ja9dVw2QhBcg_vV-1fkiCg)
* [二叉树:搜索树中的插入操作](https://mp.weixin.qq.com/s/lwKkLQcfbCNX2W-5SOeZEA)
* [二叉树:搜索树中的删除操作](https://mp.weixin.qq.com/s/-p-Txvch1FFk3ygKLjPAKw)
+ * [二叉树:修剪一棵搜索树](https://mp.weixin.qq.com/s/QzmGfYUMUWGkbRj7-ozHoQ)
+ * [二叉树:构造一棵搜索树](https://mp.weixin.qq.com/s/sy3ygnouaZVJs8lhFgl9mw)
@@ -163,6 +165,7 @@
* 循环不变量原则
* [0035.搜索插入位置](https://mp.weixin.qq.com/s/fCf5QbPDtE6SSlZ1yh_q8Q)
* [0059.螺旋矩阵II](https://mp.weixin.qq.com/s/KTPhaeqxbMK9CxHUUgFDmg)
+ * [106.从中序与后序遍历序列构造二叉树&105. 从前序与中序遍历序列构造二叉树](https://mp.weixin.qq.com/s/7r66ap2s-shvVvlZxo59xg)
* 字符串经典题目
* [0344.反转字符串](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA)
@@ -205,19 +208,46 @@
* [0144.二叉树的前序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0144.二叉树的前序遍历.md)
* [0094.二叉树的中序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0094.二叉树的中序遍历.md)
* [0145.二叉树的后序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0145.二叉树的后序遍历.md)
+ * [0589.N叉树的前序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0589.N叉树的前序遍历.md)
+ * [0590.N叉树的后序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0590.N叉树的后序遍历.md)
+
+
* [0102.二叉树的层序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0102.二叉树的层序遍历.md)
+ * [0107.二叉树的层次遍历II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0107.二叉树的层次遍历II.md)
+
* [0199.二叉树的右视图](https://github.com/youngyangyang04/leetcode/blob/master/problems/0199.二叉树的右视图.md)
+ * [0637.二叉树的层平均值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0637.二叉树的层平均值.md)
+
* [0226.翻转二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0226.翻转二叉树.md)
* [0101.对称二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0101.对称二叉树.md)
+ * [0100.相同的树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0100.相同的树.md)
+
+ * [0572.另一个树的子树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0572.另一个树的子树.md)
+ * [0110.平衡二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0110.平衡二叉树.md)
* [0104.二叉树的最大深度](https://github.com/youngyangyang04/leetcode/blob/master/problems/0104.二叉树的最大深度.md)
* [0111.二叉树的最小深度](https://github.com/youngyangyang04/leetcode/blob/master/problems/0111.二叉树的最小深度.md)
* [0222.完全二叉树的节点个数](https://github.com/youngyangyang04/leetcode/blob/master/problems/0222.完全二叉树的节点个数.md)
+ * [0404.左叶子之和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0404.左叶子之和.md)
+ * [0513.找树左下角的值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0513.找树左下角的值.md)
+ * [0112.路径总和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0112.路径总和.md)
+ * [0113.路径总和II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0113.路径总和II.md)
+ * [0257.二叉树的所有路径](https://github.com/youngyangyang04/leetcode/blob/master/problems/0257.二叉树的所有路径.md)
+ * [0236.二叉树的最近公共祖先](https://github.com/youngyangyang04/leetcode/blob/master/problems/0236.二叉树的最近公共祖先.md)
+ * [0106.从中序与后序遍历序列构造二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0106.从中序与后序遍历序列构造二叉树.md)
+ * [0105.从前序与中序遍历序列构造二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0105.从前序与中序遍历序列构造二叉树.md)
* [0654.最大二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0654.最大二叉树.md)
* [0617.合并二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0617.合并二叉树.md)
* [0700.二叉搜索树中的搜索](https://github.com/youngyangyang04/leetcode/blob/master/problems/0700.二叉搜索树中的搜索.md)
* [0098.验证二叉搜索树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0098.验证二叉搜索树.md)
+ * [0530.二叉搜索树的最小绝对差](https://github.com/youngyangyang04/leetcode/blob/master/problems/0530.二叉搜索树的最小绝对差.md)
+ * [0501.二叉搜索树中的众数](https://github.com/youngyangyang04/leetcode/blob/master/problems/0501.二叉搜索树中的众数.md)
+ * [0235.二叉搜索树的最近公共祖先](https://github.com/youngyangyang04/leetcode/blob/master/problems/0235.二叉搜索树的最近公共祖先.md)
* [0701.二叉搜索树中的插入操作](https://github.com/youngyangyang04/leetcode/blob/master/problems/0701.二叉搜索树中的插入操作.md)
* [0450.删除二叉搜索树中的节点](https://github.com/youngyangyang04/leetcode/blob/master/problems/0450.删除二叉搜索树中的节点.md)
+ * [0669.修剪二叉搜索树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0669.修剪二叉搜索树.md)
+ * [0108.将有序数组转换为二叉搜索树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0108.将有序数组转换为二叉搜索树.md)
+ * [0538.把二叉搜索树转换为累加树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0538.把二叉搜索树转换为累加树.md)
+ * [0968.监控二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0968.监控二叉树.md)
* 回溯经典题目
@@ -278,15 +308,17 @@
|[0094.二叉树的中序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0094.二叉树的中序遍历.md) |树 |中等|**递归** **迭代/栈**|
|[0098.验证二叉搜索树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0098.验证二叉搜索树.md) |树 |中等|**递归**|
|[0100.相同的树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0100.相同的树.md) |树 |简单|**递归** |
-|[0101.对称二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0101.对称二叉树.md) |树 |简单|**递归** **迭代/队列/栈**|
+|[0101.对称二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0101.对称二叉树.md) |树 |简单|**递归** **迭代/队列/栈** 和100. 相同的树 相似|
|[0102.二叉树的层序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0102.二叉树的层序遍历.md) |树 |中等|**广度优先搜索/队列**|
|[0104.二叉树的最大深度](https://github.com/youngyangyang04/leetcode/blob/master/problems/0104.二叉树的最大深度.md) |树 |简单|**递归** **迭代/队列/BFS**|
-|[0105.从前序与中序遍历序列构造二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0105.从前序与中序遍历序列构造二叉树.md) |树 |中等|**递归**|
-|[0106.从中序与后序遍历序列构造二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0106.从中序与后序遍历序列构造二叉树.md) |树 |中等|**递归**|
+|[0105.从前序与中序遍历序列构造二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0105.从前序与中序遍历序列构造二叉树.md) |二叉树 |中等|**递归**|
+|[0106.从中序与后序遍历序列构造二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0106.从中序与后序遍历序列构造二叉树.md) |二叉树 |中等|**递归** 根据数组构造二叉树|
|[0107.二叉树的层次遍历II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0107.二叉树的层次遍历II.md) |树 |简单|**广度优先搜索/队列/BFS**|
-|[0110.平衡二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0110.平衡二叉树.md) |树 |简单|**递归**|
-|[0111.二叉树的最小深度](https://github.com/youngyangyang04/leetcode/blob/master/problems/0111.二叉树的最小深度.md) |树 |简单|**递归** **队列/BFS**|
-|[0112.路径总和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0112.路径总和.md) |树 |简单|**深度优先搜索/递归** **回溯** **栈**|
+|[0108.将有序数组转换为二叉搜索树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0108.将有序数组转换为二叉搜索树.md) |二叉搜索树 |中等|**递归** **迭代** 通过递归函数返回值构造树|
+|[0110.平衡二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0110.平衡二叉树.md) |二叉树 |简单|**递归**|
+|[0111.二叉树的最小深度](https://github.com/youngyangyang04/leetcode/blob/master/problems/0111.二叉树的最小深度.md) |二叉树 |简单|**递归** **队列/BFS**|
+|[0112.路径总和](https://github.com/youngyangyang04/leetcode/blob/master/problems/0112.路径总和.md) |二叉树树 |简单|**深度优先搜索/递归** **回溯** **栈** 思考递归函数什么时候需要返回值|
+|[0113.路径总和II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0113.路径总和II.md) |二叉树树 |简单|**深度优先搜索/递归** **回溯** **栈**|
|[0116.填充每个节点的下一个右侧节点指针](https://github.com/youngyangyang04/leetcode/blob/master/problems/0116.填充每个节点的下一个右侧节点指针.md) |二叉树 |中等|**递归** **迭代/广度优先搜索**|
|[0117.填充每个节点的下一个右侧节点指针II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0117.填充每个节点的下一个右侧节点指针II.md) |二叉树 |中等|**递归** **迭代/广度优先搜索**|
|[0131.分割回文串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0131.分割回文串.md) |回溯 |中等|**回溯**|
@@ -311,7 +343,7 @@
|[0226.翻转二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0226.翻转二叉树.md) |二叉树 |简单| **递归** **迭代**|
|[0232.用栈实现队列](https://github.com/youngyangyang04/leetcode/blob/master/problems/0232.用栈实现队列.md) | 栈 |简单| **栈** |
|[0235.二叉搜索树的最近公共祖先](https://github.com/youngyangyang04/leetcode/blob/master/problems/0235.二叉搜索树的最近公共祖先.md) | 二叉搜索树 |简单| **递归** **迭代** |
-|[0236.二叉树的最近公共祖先](https://github.com/youngyangyang04/leetcode/blob/master/problems/0236.二叉树的最近公共祖先.md) | 二叉树 |中等| **递归/回溯** |
+|[0236.二叉树的最近公共祖先](https://github.com/youngyangyang04/leetcode/blob/master/problems/0236.二叉树的最近公共祖先.md) | 二叉树 |中等| **递归/回溯** 与其说是递归,不如说是回溯|
|[0237.删除链表中的节点](https://github.com/youngyangyang04/leetcode/blob/master/problems/0237.删除链表中的节点.md) |链表 |简单| **原链表移除** **添加虚拟节点** 递归|
|[0239.滑动窗口最大值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0239.滑动窗口最大值.md) |滑动窗口/队列 |困难| **单调队列**|
|[0242.有效的字母异位词](https://github.com/youngyangyang04/leetcode/blob/master/problems/0242.有效的字母异位词.md) |哈希表 |简单| **哈希**|
@@ -336,29 +368,32 @@
|[0513.找树左下角的值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0513.找树左下角的值.md) |二叉树 |中等|**递归** **迭代**|
|[0515.在每个树行中找最大值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0515.在每个树行中找最大值.md) |二叉树 |简单|**广度优先搜索/队列**|
|[0530.二叉搜索树的最小绝对差](https://github.com/youngyangyang04/leetcode/blob/master/problems/0530.二叉搜索树的最小绝对差.md) |二叉树搜索树 |简单|**递归** **迭代**|
-|[0538.把二叉搜索树转换为累加树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0538.把二叉搜索树转换为累加树.md) |二叉树 |简单|**递归** **迭代**|
+|[0538.把二叉搜索树转换为累加树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0538.把二叉搜索树转换为累加树.md) |二叉搜索树 |简单|**递归** **迭代**|
|[0541.反转字符串II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0541.反转字符串II.md) |字符串 |简单| **模拟**|
|[0559.N叉树的最大深度](https://github.com/youngyangyang04/leetcode/blob/master/problems/0559.N叉树的最大深度.md) |N叉树 |简单| **递归**|
|[0572.另一个树的子树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0572.另一个树的子树.md) |二叉树 |简单| **递归**|
|[0575.分糖果](https://github.com/youngyangyang04/leetcode/blob/master/problems/0575.分糖果.md) |哈希表 |简单|**哈希**|
-|[0589.N叉树的前序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0589.N叉树的前序遍历.md) |树 |简单|**递归** **栈/迭代**|
-|[0590.N叉树的后序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0590.N叉树的后序遍历.md) |树 |简单|**递归** **栈/迭代**|
+|[0589.N叉树的前序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0589.N叉树的前序遍历.md) |N叉树 |简单|**递归** **栈/迭代**|
+|[0590.N叉树的后序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0590.N叉树的后序遍历.md) |N叉树 |简单|**递归** **栈/迭代**|
|[0617.合并二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0617.合并二叉树.md) |树 |简单|**递归** **迭代**|
|[0637.二叉树的层平均值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0637.二叉树的层平均值.md) |树 |简单|**广度优先搜索/队列**|
|[0654.最大二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0654.最大二叉树.md) |树 |中等|**递归**|
|[0685.冗余连接II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0685.冗余连接II.md) | 并查集/树/图 |困难|**并查集**|
|[0669.修剪二叉搜索树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0669.修剪二叉搜索树.md) | 二叉搜索树/二叉树 |简单|**递归** **迭代**|
-|[0700.二叉搜索树中的搜索](https://github.com/youngyangyang04/leetcode/blob/master/problems/0700.二叉搜索树中的搜索.md) |树 |简单|**递归** **迭代**|
-|[0701.二叉搜索树中的插入操作](https://github.com/youngyangyang04/leetcode/blob/master/problems/0701.二叉搜索树中的插入操作.md) |树 |简单|**递归** **迭代**|
+|[0700.二叉搜索树中的搜索](https://github.com/youngyangyang04/leetcode/blob/master/problems/0700.二叉搜索树中的搜索.md) |二叉搜索树 |简单|**递归** **迭代**|
+|[0701.二叉搜索树中的插入操作](https://github.com/youngyangyang04/leetcode/blob/master/problems/0701.二叉搜索树中的插入操作.md) |二叉搜索树 |简单|**递归** **迭代**|
|[0705.设计哈希集合](https://github.com/youngyangyang04/leetcode/blob/master/problems/0705.设计哈希集合.md) |哈希表 |简单|**模拟**|
|[0707.设计链表](https://github.com/youngyangyang04/leetcode/blob/master/problems/0707.设计链表.md) |链表 |中等|**模拟**|
+|[0763.划分字母区间](https://github.com/youngyangyang04/leetcode/blob/master/problems/0763.划分字母区间.md) |贪心 |中等|**双指针/贪心** 体现贪心尽可能多的思想|
|[0739.每日温度](https://github.com/youngyangyang04/leetcode/blob/master/problems/0739.每日温度.md) |栈 |中等|**单调栈** 适合单调栈入门|
|[0841.钥匙和房间](https://github.com/youngyangyang04/leetcode/blob/master/problems/0841.钥匙和房间.md) |孤岛问题 |中等|**bfs** **dfs**|
|[0844.比较含退格的字符串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0844.比较含退格的字符串.md) |字符串 |简单|**栈** **双指针优化** 使用栈的思路但没有必要使用栈|
|[0925.长按键入](https://github.com/youngyangyang04/leetcode/blob/master/problems/0925.长按键入.md) |字符串 |简单|**双指针/模拟** 是一道模拟类型的题目|
+|[0968.监控二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0968.监控二叉树.md) |二叉树 |困难|**贪心** 贪心与二叉树的结合|
|[0977.有序数组的平方](https://github.com/youngyangyang04/leetcode/blob/master/problems/0977.有序数组的平方.md) |数组 |中等|**双指针** 还是比较巧妙的|
|[1002.查找常用字符](https://github.com/youngyangyang04/leetcode/blob/master/problems/1002.查找常用字符.md) |栈 |简单|**栈**|
|[1047.删除字符串中的所有相邻重复项](https://github.com/youngyangyang04/leetcode/blob/master/problems/1047.删除字符串中的所有相邻重复项.md) |哈希表 |简单|**哈希表/数组**|
+|[1382.将二叉搜索树变平衡](https://github.com/youngyangyang04/leetcode/blob/master/problems/1047.删除字符串中的所有相邻重复项.md) |二叉搜索树 |中等|**递归** **迭代** 98和108的组合题目|
|[剑指Offer05.替换空格](https://github.com/youngyangyang04/leetcode/blob/master/problems/剑指Offer05.替换空格.md) |字符串 |简单|**双指针**|
|[ 剑指Offer58-I.翻转单词顺序](https://github.com/youngyangyang04/leetcode/blob/master/problems/剑指Offer05.替换空格.md) |字符串 |简单|**模拟/双指针**|
|[剑指Offer58-II.左旋转字符串](https://github.com/youngyangyang04/leetcode/blob/master/problems/剑指Offer58-II.左旋转字符串.md) |字符串 |简单|**反转操作**|
diff --git a/pics/108.将有序数组转换为二叉搜索树.png b/pics/108.将有序数组转换为二叉搜索树.png
new file mode 100644
index 00000000..7d25f99d
Binary files /dev/null and b/pics/108.将有序数组转换为二叉搜索树.png differ
diff --git a/pics/234.回文链表.png b/pics/234.回文链表.png
new file mode 100644
index 00000000..285c73bb
Binary files /dev/null and b/pics/234.回文链表.png differ
diff --git a/pics/538.把二叉搜索树转换为累加树.png b/pics/538.把二叉搜索树转换为累加树.png
index 1417fef9..27077f7b 100644
Binary files a/pics/538.把二叉搜索树转换为累加树.png and b/pics/538.把二叉搜索树转换为累加树.png differ
diff --git a/pics/763.划分字母区间.png b/pics/763.划分字母区间.png
new file mode 100644
index 00000000..0c1da0f3
Binary files /dev/null and b/pics/763.划分字母区间.png differ
diff --git a/problems/0106.从中序与后序遍历序列构造二叉树.md b/problems/0106.从中序与后序遍历序列构造二叉树.md
index 0089d3fc..9b8295b1 100644
--- a/problems/0106.从中序与后序遍历序列构造二叉树.md
+++ b/problems/0106.从中序与后序遍历序列构造二叉树.md
@@ -3,6 +3,12 @@ https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorde
> 给出两个序列
+看完本文,可以一起解决如下两道题目
+
+* 106.从中序与后序遍历序列构造二叉树
+* 105.从前序与中序遍历序列构造二叉树
+
+
# 106.从中序与后序遍历序列构造二叉树
根据一棵树的中序遍历与后序遍历构造二叉树。
@@ -383,7 +389,7 @@ public:
};
```
-# 105. 从前序与中序遍历序列构造二叉树
+# 105.从前序与中序遍历序列构造二叉树
根据一棵树的前序遍历与中序遍历构造二叉树。
diff --git a/problems/0108.将有序数组转换为二叉搜索树.md b/problems/0108.将有序数组转换为二叉搜索树.md
index 6a406ffd..3afc8d6a 100644
--- a/problems/0108.将有序数组转换为二叉搜索树.md
+++ b/problems/0108.将有序数组转换为二叉搜索树.md
@@ -1,28 +1,122 @@
+> 构造二叉搜索树,一不小心就平衡了
-## 思路
+# 108.将有序数组转换为二叉搜索树
-要考率 和 普通数组转成二叉树有什么差别
+将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
-注意这里是构造平衡二叉搜索树,其实 这里不用强调,因为数组构造二叉树,构成平衡树是自然而然的事情,因为大家默认都是从中间取值,不可能随机取,自找麻烦
+本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
-一想 这道题目还是有难度的,
+示例:
-一定是递归 分治
+
-循环不变量 的题目列表
+# 思路
-注意答案不是唯一的
+做这道题目之前大家可以了解一下这几道:
-输入:[-10,-3,0,5,9]
-输出:[0,-10,5,null,-3,null,9]
-预期结果:[0,-3,9,-10,null,5]
+* [106.从中序与后序遍历序列构造二叉树](https://mp.weixin.qq.com/s/7r66ap2s-shvVvlZxo59xg)
+* [654.最大二叉树](https://mp.weixin.qq.com/s/1iWJV6Aov23A7xCF4nV88w)中其实已经讲过了,如果根据数组构造一颗二叉树。
+* [701.二叉搜索树中的插入操作](https://mp.weixin.qq.com/s/lwKkLQcfbCNX2W-5SOeZEA)
+* [450.删除二叉搜索树中的节点](https://mp.weixin.qq.com/s/-p-Txvch1FFk3ygKLjPAKw)
+
+
+进入正题:
+
+题目中说要转换为一棵高度平衡二叉搜索树。这和转换为一棵普通二叉搜索树有什么差别呢?
+
+其实这里不用强调平衡二叉搜索树,数组构造二叉树,构成平衡树是自然而然的事情,因为大家默认都是从数组中间位置取值作为节点元素,一般不会随机取,**所以想构成不平衡的二叉树是自找麻烦**。
+
+
+在[二叉树:构造二叉树登场!](https://mp.weixin.qq.com/s/7r66ap2s-shvVvlZxo59xg)和[二叉树:构造一棵最大的二叉树](https://mp.weixin.qq.com/s/1iWJV6Aov23A7xCF4nV88w)中其实已经讲过了,如果根据数组构造一颗二叉树。
+
+**本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间**。
+
+本题其实要比[二叉树:构造二叉树登场!](https://mp.weixin.qq.com/s/7r66ap2s-shvVvlZxo59xg) 和 [二叉树:构造一棵最大的二叉树](https://mp.weixin.qq.com/s/1iWJV6Aov23A7xCF4nV88w)简单一些,因为有序数组构造二叉搜索树,寻找分割点就比较容易了。
+
+分割点就是数组中间位置的节点。
+
+那么为问题来了,如果数组长度为偶数,中间节点有两个,取哪一个?
+
+取哪一个都可以,只不过构成了不同的平衡二叉搜索树。
+
+例如:输入:[-10,-3,0,5,9]
+
+如下两棵树,都是这个数组的平衡二叉搜索树:
+
+
+
+如果要分割的数组长度为偶数的时候,中间元素为两个,是取左边元素 就是树1,取右边元素就是树2。
+
+**这也是题目中强调答案不是唯一的原因。 理解这一点,这道题目算是理解到位了**。
+
+## 递归
+
+递归三部曲:
+
+* 确定递归函数返回值及其参数
+
+删除二叉树节点,增加二叉树节点,都是用递归函数的返回值来完成,这样是比较方便的。
+
+相信大家如果仔细看了[二叉树:搜索树中的插入操作](https://mp.weixin.qq.com/s/lwKkLQcfbCNX2W-5SOeZEA)和[二叉树:搜索树中的删除操作](https://mp.weixin.qq.com/s/-p-Txvch1FFk3ygKLjPAKw),一定会对递归函数返回值的作用深有感触。
+
+那么本题要构造二叉树,依然用递归函数的返回值来构造中节点的左右孩子。
+
+再来看参数,首先是传入数组,然后就是左下表left和右下表right,我们在[二叉树:构造二叉树登场!](https://mp.weixin.qq.com/s/7r66ap2s-shvVvlZxo59xg)中提过,在构造二叉树的时候尽量不要重新定义左右区间数组,而是用下表来操作原数组。
+
+所以代码如下:
+
+```
+// 左闭右闭区间[left, right]
+TreeNode* traversal(vector& nums, int left, int right)
+```
+
+这里注意,**我这里定义的是左闭右闭区间,在不断分割的过程中,也会坚持左闭右闭的区间,这又涉及到我们讲过的循环不变量**。
+
+在[二叉树:构造二叉树登场!](https://mp.weixin.qq.com/s/7r66ap2s-shvVvlZxo59xg),[35.搜索插入位置](https://mp.weixin.qq.com/s/fCf5QbPDtE6SSlZ1yh_q8Q) 和[59.螺旋矩阵II](https://mp.weixin.qq.com/s/KTPhaeqxbMK9CxHUUgFDmg)都详细讲过循环不变量。
+
+
+* 确定递归终止条件
+
+这里定义的是左闭右闭的区间,所以当区间 left > right的时候,就是空节点了。
+
+代码如下:
+
+```
+if (left > right) return nullptr;
+```
+
+* 确定单层递归的逻辑
+
+首先取数组中间元素的位置,不难写出`int mid = (left + right) / 2;`,**这么写其实有一个问题,就是数值越界,例如left和right都是最大int,这么操作就越界了,在[二分法](https://mp.weixin.qq.com/s/fCf5QbPDtE6SSlZ1yh_q8Q)中尤其需要注意!**
+
+所以可以这么写:`int mid = left + ((right - left) / 2);`
+
+但本题leetcode的测试数据并不会越界,所以怎么写都可以。但需要有这个意识!
+
+取了中间位置,就开始以中间位置的元素构造节点,代码:`TreeNode* root = new TreeNode(nums[mid]);`。
+
+接着划分区间,root的左孩子接住下一层左区间的构造节点,右孩子接住下一层右区间构造的节点。
+
+最后返回root节点,单层递归整体代码如下:
+
+```
+int mid = left + ((right - left) / 2);
+TreeNode* root = new TreeNode(nums[mid]);
+root->left = traversal(nums, left, mid - 1);
+root->right = traversal(nums, mid + 1, right);
+return root;
+```
+
+这里`int mid = left + ((right - left) / 2);`的写法相当于是如果数组长度为偶数,中间位置有两个元素,取靠左边的。
+
+* 递归整体代码如下:
```
class Solution {
private:
TreeNode* traversal(vector& nums, int left, int right) {
if (left > right) return nullptr;
- int mid = (left + right) / 2; // 注意越界
+ int mid = left + ((right - left) / 2);
TreeNode* root = new TreeNode(nums[mid]);
root->left = traversal(nums, left, mid - 1);
root->right = traversal(nums, mid + 1, right);
@@ -36,3 +130,68 @@ public:
};
```
+**注意:在调用traversal的时候为什么传入的left和right为什么是0和nums.size() - 1,因为定义的区间为左闭右闭**。
+
+
+## 迭代法
+
+迭代法可以通过三个队列来模拟,一个队列放遍历的节点,一个队列放左区间下表,一个队列放右区间下表。
+
+模拟的就是不断分割的过程,C++代码如下:(我已经详细注释)
+
+```
+class Solution {
+public:
+ TreeNode* sortedArrayToBST(vector& nums) {
+ if (nums.size() == 0) return nullptr;
+
+ TreeNode* root = new TreeNode(0); // 初始根节点
+ queue nodeQue; // 放遍历的节点
+ queue leftQue; // 保存左区间下表
+ queue rightQue; // 保存右区间下表
+ nodeQue.push(root); // 根节点入队列
+ leftQue.push(0); // 0为左区间下表初始位置
+ rightQue.push(nums.size() - 1); // nums.size() - 1为右区间下表初始位置
+
+ while (!nodeQue.empty()) {
+ TreeNode* curNode = nodeQue.front();
+ nodeQue.pop();
+ int left = leftQue.front(); leftQue.pop();
+ int right = rightQue.front(); rightQue.pop();
+ int mid = left + ((right - left) / 2);
+
+ curNode->val = nums[mid]; // 将mid对应的元素给中间节点
+
+ if (left <= mid - 1) { // 处理左区间
+ curNode->left = new TreeNode(0);
+ nodeQue.push(curNode->left);
+ leftQue.push(left);
+ rightQue.push(mid - 1);
+ }
+
+ if (right >= mid + 1) { // 处理右区间
+ curNode->right = new TreeNode(0);
+ nodeQue.push(curNode->right);
+ leftQue.push(mid + 1);
+ rightQue.push(right);
+ }
+ }
+ return root;
+ }
+};
+```
+
+# 总结
+
+**在[二叉树:构造二叉树登场!](https://mp.weixin.qq.com/s/7r66ap2s-shvVvlZxo59xg) 和 [二叉树:构造一棵最大的二叉树](https://mp.weixin.qq.com/s/1iWJV6Aov23A7xCF4nV88w)之后,我们顺理成章的应该构造一下二叉搜索树了,一不小心还是一棵平衡二叉搜索树**。
+
+其实思路也是一样的,不断中间分割,然后递归处理左区间,右区间,也可以说是分治。
+
+此时相信大家应该对通过递归函数的返回值来增删二叉树很熟悉了,这也是常规操作。
+
+在定义区间的过程中我们又一次强调了循环不变量的重要性。
+
+最后依然给出迭代的方法,其实就是模拟取中间元素,然后不断分割去构造二叉树的过程。
+
+**就酱,如果对你有帮助的话,也转发给身边需要的同学吧!**
+
diff --git a/problems/0234.回文链表.md b/problems/0234.回文链表.md
new file mode 100644
index 00000000..d37044d7
--- /dev/null
+++ b/problems/0234.回文链表.md
@@ -0,0 +1,122 @@
+
+## 题目链接
+https://leetcode-cn.com/problems/palindrome-linked-list/
+
+## 思路
+
+### 数组模拟
+
+最直接的想法,就是把链表装成数组,然后再判断是否回文。
+
+代码也比较简单。如下:
+
+```
+class Solution {
+public:
+ bool isPalindrome(ListNode* head) {
+ vector vec;
+ ListNode* cur = head;
+ while (cur) {
+ vec.push_back(cur->val);
+ cur = cur->next;
+ }
+ // 比较数组回文
+ for (int i = 0, j = vec.size() - 1; i < j; i++, j--) {
+ if (vec[i] != vec[j]) return false;
+ }
+ return true;
+ }
+};
+```
+
+上面代码可以在优化,就是先求出链表长度,然后给定vector的初始长度,这样避免vector每次添加节点重新开辟空间
+
+```
+class Solution {
+public:
+ bool isPalindrome(ListNode* head) {
+
+ ListNode* cur = head;
+ int length = 0;
+ while (cur) {
+ length++;
+ cur = cur->next;
+ }
+ vector vec(length, 0); // 给定vector的初始长度,这样避免vector每次添加节点重新开辟空间
+ cur = head;
+ int index = 0;
+ while (cur) {
+ vec[index++] = cur->val;
+ cur = cur->next;
+ }
+ // 比较数组回文
+ for (int i = 0, j = vec.size() - 1; i < j; i++, j--) {
+ if (vec[i] != vec[j]) return false;
+ }
+ return true;
+ }
+};
+
+```
+
+### 反转后半部分链表
+
+分为如下几步:
+
+* 用快慢指针,快指针有两步,慢指针走一步,快指针遇到终止位置时,慢指针就在链表中间位置
+* 同时用pre记录慢指针指向节点的前一个节点,用来分割链表
+* 将链表分为前后均等两部分,如果链表长度是奇数,那么后半部分多一个节点
+* 将后半部分反转 ,得cur2,前半部分为cur1
+* 按照cur1的长度,一次比较cur1和cur2的节点数值
+
+如图所示:
+
+
+
+代码如下:
+
+```
+class Solution {
+public:
+ bool isPalindrome(ListNode* head) {
+ if (head == nullptr || head->next == nullptr) return true;
+ ListNode* slow = head; // 慢指针,找到链表中间分位置,作为分割
+ ListNode* fast = head;
+ ListNode* pre = head; // 记录慢指针的前一个节点,用来分割链表
+ while (fast && fast->next) {
+ pre = slow;
+ slow = slow->next;
+ fast = fast->next->next;
+ }
+ pre->next = nullptr; // 分割链表
+
+ ListNode* cur1 = head; // 前半部分
+ ListNode* cur2 = reverseList(slow); // 反转后半部分,总链表长度如果是奇数,cur2比cur1多一个节点
+
+ // 开始两个链表的比较
+ while (cur1) {
+ if (cur1->val != cur2->val) return false;
+ cur1 = cur1->next;
+ cur2 = cur2->next;
+ }
+ return true;
+ }
+ // 反转链表
+ ListNode* reverseList(ListNode* head) {
+ ListNode* temp; // 保存cur的下一个节点
+ ListNode* cur = head;
+ ListNode* pre = nullptr;
+ while(cur) {
+ temp = cur->next; // 保存一下 cur的下一个节点,因为接下来要改变cur->next
+ cur->next = pre; // 翻转操作
+ // 更新pre 和 cur指针
+ pre = cur;
+ cur = temp;
+ }
+ return pre;
+ }
+};
+```
+
+栈
+
diff --git a/problems/0402.移掉K位数字.md b/problems/0402.移掉K位数字.md
new file mode 100644
index 00000000..c7112bff
--- /dev/null
+++ b/problems/0402.移掉K位数字.md
@@ -0,0 +1,11 @@
+
+## 思路
+
+https://www.cnblogs.com/gzshan/p/12560566.html 图不错
+
+有点难度
+
+
+暴力的解法,其实也不是那么好写的, 首字符去0,k没消耗完,等等这些情况
+
+有点难,卡我很久
diff --git a/problems/0538.把二叉搜索树转换为累加树.md b/problems/0538.把二叉搜索树转换为累加树.md
index f50a03f1..84dada49 100644
--- a/problems/0538.把二叉搜索树转换为累加树.md
+++ b/problems/0538.把二叉搜索树转换为累加树.md
@@ -3,28 +3,109 @@
https://leetcode-cn.com/problems/convert-bst-to-greater-tree/
-## 思路
+> 祝大家1024节日快乐!!
-一看到累加树,相信很多小伙伴一脸懵逼,如何累加,遇到一个节点,然后在遍历其他节点累加?怎么一想这么麻烦呢。
+今天应该是一个程序猿普天同庆的日子,所以今天的题目比较简单,只要认真把前面每天的文章都看了,今天的题目就是分分钟的事了,大家可以愉快过节!
-然后发现这是一颗二叉搜索树,二叉搜索树啊,这是有序的啊。
+# 538.把二叉搜索树转换为累加树
+
+题目链接:https://leetcode-cn.com/problems/convert-bst-to-greater-tree/
+
+给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
+
+提醒一下,二叉搜索树满足下列约束条件:
+
+节点的左子树仅包含键 小于 节点键的节点。
+节点的右子树仅包含键 大于 节点键的节点。
+左右子树也必须是二叉搜索树。
+
+示例 1:
+
+
+
+输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
+输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
+
+示例 2:
+输入:root = [0,null,1]
+输出:[1,null,1]
+
+示例 3:
+输入:root = [1,0,2]
+输出:[3,3,2]
+
+示例 4:
+输入:root = [3,2,4,1]
+输出:[7,9,4,10]
+
+提示:
+
+* 树中的节点数介于 0 和 104 之间。
+* 每个节点的值介于 -104 和 104 之间。
+* 树中的所有值 互不相同 。
+* 给定的树为二叉搜索树。
+
+# 思路
+
+一看到累加树,相信很多小伙伴都会疑惑:如何累加?遇到一个节点,然后在遍历其他节点累加?怎么一想这么麻烦呢。
+
+然后再发现这是一颗二叉搜索树,二叉搜索树啊,这是有序的啊。
那么有序的元素如果求累加呢?
-**其实这就是一棵树,大家可能看起来有点别扭,换一个角度来看,这就是一个有序数组[2, 5, 13],求从后到前的累加数组,也就是[20, 18, 13],大家是不是感觉这就是送分题了。**
+**其实这就是一棵树,大家可能看起来有点别扭,换一个角度来看,这就是一个有序数组[2, 5, 13],求从后到前的累加数组,也就是[20, 18, 13],是不是感觉这就简单了。**
-为什么变成数组就是送分题了呢,因为数组大家都知道怎么遍历啊,从后向前,挨个累加就完事了,这换成了二叉搜索树,看起来就别扭了一些是不是。
+为什么变成数组就是感觉简单了呢?
-那么知道如何遍历这个二叉树,也就迎刃而解了,从树中可以看出累加的顺讯是 右中左,所以我们需要中序遍历反过来遍历这个二叉树,然后顺序累加就可以了。
+因为数组大家都知道怎么遍历啊,从后向前,挨个累加就完事了,这换成了二叉搜索树,看起来就别扭了一些是不是。
+
+那么知道如何遍历这个二叉树,也就迎刃而解了,**从树中可以看出累加的顺序是右中左,所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了**。
+
+## 递归
遍历顺序如图所示:
+本题依然需要一个pre指针记录当前遍历节点cur的前一个节点,这样才方便做累加。
-以下我给出一种递归的写法,两种迭代法的写法,别问我为什么写出了这么多写法,把我写的这个题解[彻底吃透二叉树的前中后序递归法和迭代法!!](https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/che-di-chi-tou-er-cha-shu-de-qian-zhong-hou-xu-d-2/)看了,你也能分分钟写出来三种写法![机智]
+pre指针的使用技巧,我们在[二叉树:搜索树的最小绝对差](https://mp.weixin.qq.com/s/Hwzml6698uP3qQCC1ctUQQ)和[二叉树:我的众数是多少?](https://mp.weixin.qq.com/s/KSAr6OVQIMC-uZ8MEAnGHg)都提到了,这是常用的操作手段。
-## C++递归代码
+* 递归函数参数以及返回值
+
+这里很明确了,不需要递归函数的返回值做什么操作了,要遍历整棵树。
+
+同时需要定义一个全局变量pre,用来保存cur节点的前一个节点的数值,定义为int型就可以了。
+
+代码如下:
+
+```
+int pre; // 记录前一个节点的数值
+void traversal(TreeNode* cur)
+```
+
+* 确定终止条件
+
+遇空就终止。
+
+```
+if (cur == NULL) return;
+```
+
+* 确定单层递归的逻辑
+
+注意**要右中左来遍历二叉树**, 中节点的处理逻辑就是让cur的数值加上前一个节点的数值。
+
+代码如下:
+
+```
+traversal(cur->right); // 右
+cur->val += pre; // 中
+pre = cur->val;
+traversal(cur->left); // 左
+```
+
+递归法整体代码如下:
```
class Solution {
@@ -46,7 +127,11 @@ public:
};
```
-## C++迭代法(一)代码
+## 迭代法
+
+迭代法其实就是中序模板题了,在[二叉树:前中后序迭代法](https://mp.weixin.qq.com/s/c_zCrGHIVlBjUH_hJtghCg)和[二叉树:前中后序统一方式迭代法](https://mp.weixin.qq.com/s/WKg0Ty1_3SZkztpHubZPRg)可以选一种自己习惯的写法。
+
+这里我给出其中的一种,代码如下:
```
class Solution {
@@ -77,40 +162,12 @@ public:
};
```
-## C++迭代法(二)代码
+# 总结
-```
-class Solution {
-private:
- int pre; // 记录前一个节点的数值
- void traversal(TreeNode* root) {
- stack st;
- if (root != NULL) st.push(root);
- while (!st.empty()) {
- TreeNode* node = st.top();
- if (node != NULL) {
- st.pop();
- if (node->left) st.push(node->left); // 左
+经历了前面各种二叉树增删改查的洗礼之后,这道题目应该比较简单了。
- st.push(node); // 中
- st.push(NULL);
+**好了,二叉树已经接近尾声了,接下来就是要对二叉树来一个大总结了**。
+
+最后再次祝大家1024节日快乐,哈哈哈!
- if (node->right) st.push(node->right); // 右
- } else {
- st.pop();
- node = st.top();
- st.pop();
- node->val += pre; // 处理中间节点
- pre = node->val;
- }
- }
- }
-public:
- TreeNode* convertBST(TreeNode* root) {
- pre = 0;
- traversal(root);
- return root;
- }
-};
-```
diff --git a/problems/0669.修剪二叉搜索树.md b/problems/0669.修剪二叉搜索树.md
index d8e40aba..641416b0 100644
--- a/problems/0669.修剪二叉搜索树.md
+++ b/problems/0669.修剪二叉搜索树.md
@@ -97,7 +97,7 @@ if (root->val < low) {
}
```
-如果root(当前节点)的元素小于high的,那么应该递归左子树,并返回左子树符合条件的头结点。
+如果root(当前节点)的元素大于high的,那么应该递归左子树,并返回左子树符合条件的头结点。
代码如下:
diff --git a/problems/0739.每日温度.md b/problems/0739.每日温度.md
index 83acc50d..12d9a55f 100644
--- a/problems/0739.每日温度.md
+++ b/problems/0739.每日温度.md
@@ -51,3 +51,4 @@ public:
}
};
```
+> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
diff --git a/problems/0763.划分字母区间.md b/problems/0763.划分字母区间.md
new file mode 100644
index 00000000..6a0716a3
--- /dev/null
+++ b/problems/0763.划分字母区间.md
@@ -0,0 +1,41 @@
+## 题目链接
+https://leetcode-cn.com/problems/partition-labels/
+
+## 思路
+
+一想到分割字符串就想到了回溯,但本题其实不用那么复杂。
+
+可以分为如下两步:
+
+* 统计每一个字符最后出现的位置
+* 从头遍历字符,如果找到之前字符最大出现位置下标和当前下标相等,则找到了分割点
+
+如图:
+
+
+
+明白原理之后,代码并不复杂,如下:
+
+```
+class Solution {
+public:
+ vector partitionLabels(string S) {
+ int hash[27] = {0}; // i为字符,hash[i]为字符出现的最后位置
+ for (int i = 0; i < S.size(); i++) { // 统计每一个字符最后出现的位置
+ hash[S[i] - 'a'] = i;
+ }
+ vector result;
+ int left = 0;
+ int right = 0;
+ for (int i = 0; i < S.size(); i++) {
+ right = max(right, hash[S[i] - 'a']); // 找到字符出现的最远边界
+ if (i == right) {
+ result.push_back(right - left + 1);
+ left = i + 1;
+ }
+ }
+ return result;
+ }
+};
+```
+> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
diff --git a/problems/0841.钥匙和房间.md b/problems/0841.钥匙和房间.md
index e30d18f1..16473f1a 100644
--- a/problems/0841.钥匙和房间.md
+++ b/problems/0841.钥匙和房间.md
@@ -80,3 +80,5 @@ public:
}
};
```
+
+> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
diff --git a/problems/0844.比较含退格的字符串.md b/problems/0844.比较含退格的字符串.md
index a47bdbb3..47031a70 100644
--- a/problems/0844.比较含退格的字符串.md
+++ b/problems/0844.比较含退格的字符串.md
@@ -118,3 +118,5 @@ public:
* 时间复杂度:O(n + m)
* 空间复杂度:O(1)
+
+> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
diff --git a/problems/0925.长按键入.md b/problems/0925.长按键入.md
index 7890dd9a..6c6ba699 100644
--- a/problems/0925.长按键入.md
+++ b/problems/0925.长按键入.md
@@ -57,3 +57,5 @@ public:
时间复杂度:O(n)
空间复杂度:O(1)
+
+> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
diff --git a/problems/0968.监控二叉树.md b/problems/0968.监控二叉树.md
index dc3fec03..a5dbdefb 100644
--- a/problems/0968.监控二叉树.md
+++ b/problems/0968.监控二叉树.md
@@ -217,3 +217,4 @@ public:
}
};
```
+> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
diff --git a/problems/0977.有序数组的平方.md b/problems/0977.有序数组的平方.md
index 5f09aa76..f5ff9638 100644
--- a/problems/0977.有序数组的平方.md
+++ b/problems/0977.有序数组的平方.md
@@ -73,3 +73,4 @@ public:
一样的代码多提交几次可能就击败百分之百了.....
+> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
diff --git a/problems/1002.查找常用字符.md b/problems/1002.查找常用字符.md
index 106e8e12..f9506010 100644
--- a/problems/1002.查找常用字符.md
+++ b/problems/1002.查找常用字符.md
@@ -108,3 +108,5 @@ public:
}
};
```
+
+> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md
index 0b12c129..1962e78d 100644
--- a/problems/1047.删除字符串中的所有相邻重复项.md
+++ b/problems/1047.删除字符串中的所有相邻重复项.md
@@ -84,5 +84,27 @@ public:
};
```
+当然可以拿字符串直接作为栈,这样省去了栈还要转为字符串的操作。
+
+代码如下:
+
+```
+class Solution {
+public:
+ string removeDuplicates(string S) {
+ string result;
+ for(char s : S) {
+ if(result.empty() || result.back() != s) {
+ result.push_back(s);
+ }
+ else {
+ result.pop_back();
+ }
+ }
+ return result;
+ }
+};
+```
+
> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。
diff --git a/problems/1382.将二叉搜索树变平衡.md b/problems/1382.将二叉搜索树变平衡.md
new file mode 100644
index 00000000..9d3a2b65
--- /dev/null
+++ b/problems/1382.将二叉搜索树变平衡.md
@@ -0,0 +1,46 @@
+
+## 题目地址
+https://leetcode-cn.com/problems/balance-a-binary-search-tree/
+
+## 思路
+
+这道题目,可以中序遍历把二叉树转变为有序数组,然后在根据有序数组构造平衡二叉搜索树。
+
+建议做这道题之前,先看如下两篇题解:
+* [98.验证二叉搜索树](https://mp.weixin.qq.com/s/8odY9iUX5eSi0eRFSXFD4Q) 学习二叉搜索树的特性
+* [108.将有序数组转换为二叉搜索树](https://mp.weixin.qq.com/s/sy3ygnouaZVJs8lhFgl9mw) 学习如何通过有序数组构造二叉搜索树
+
+这两道题目做过之后,本题分分钟就可以做出来了。
+
+代码如下:
+
+```
+class Solution {
+private:
+ vector vec;
+ // 有序树转成有序数组
+ void traversal(TreeNode* cur) {
+ if (cur == nullptr) {
+ return;
+ }
+ traversal(cur->left);
+ vec.push_back(cur->val);
+ traversal(cur->right);
+ }
+ 有序数组转平衡二叉树
+ TreeNode* getTree(vector& nums, int left, int right) {
+ if (left > right) return nullptr;
+ int mid = left + ((right - left) / 2);
+ TreeNode* root = new TreeNode(nums[mid]);
+ root->left = getTree(nums, left, mid - 1);
+ root->right = getTree(nums, mid + 1, right);
+ return root;
+ }
+
+public:
+ TreeNode* balanceBST(TreeNode* root) {
+ traversal(root);
+ return getTree(vec, 0, vec.size() - 1);
+ }
+};
+```