This commit is contained in:
youngyangyang04
2020-10-22 09:15:34 +08:00
parent baf55b429a
commit 00356b6481
11 changed files with 304 additions and 24 deletions

View File

@ -69,7 +69,6 @@
* 双指针法 * 双指针法
* [数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA) * [数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA)
* [数组977. 有序数组的平方]()
* [字符串:这道题目,使用库函数一行代码搞定](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA) * [字符串:这道题目,使用库函数一行代码搞定](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA)
* [字符串:替换空格](https://mp.weixin.qq.com/s/t0A9C44zgM-RysAQV3GZpg) * [字符串:替换空格](https://mp.weixin.qq.com/s/t0A9C44zgM-RysAQV3GZpg)
* [字符串:花式反转还不够!](https://mp.weixin.qq.com/s/X3qpi2v5RSp08mO-W5Vicw) * [字符串:花式反转还不够!](https://mp.weixin.qq.com/s/X3qpi2v5RSp08mO-W5Vicw)
@ -121,6 +120,7 @@
* [本周小结!(二叉树系列四)](https://mp.weixin.qq.com/s/CbdtOTP0N-HIP7DR203tSg) * [本周小结!(二叉树系列四)](https://mp.weixin.qq.com/s/CbdtOTP0N-HIP7DR203tSg)
* [二叉树:搜索树的公共祖先问题](https://mp.weixin.qq.com/s/Ja9dVw2QhBcg_vV-1fkiCg) * [二叉树:搜索树的公共祖先问题](https://mp.weixin.qq.com/s/Ja9dVw2QhBcg_vV-1fkiCg)
* [二叉树:搜索树中的插入操作](https://mp.weixin.qq.com/s/lwKkLQcfbCNX2W-5SOeZEA) * [二叉树:搜索树中的插入操作](https://mp.weixin.qq.com/s/lwKkLQcfbCNX2W-5SOeZEA)
* [二叉树:搜索树中的删除操作](https://mp.weixin.qq.com/s/-p-Txvch1FFk3ygKLjPAKw)
@ -178,12 +178,13 @@
* [0015.三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A) * [0015.三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A)
* [0018.四数之和](https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g) * [0018.四数之和](https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g)
* [0026.删除排序数组中的重复项](https://github.com/youngyangyang04/leetcode/blob/master/problems/0026.删除排序数组中的重复项.md) * [0026.删除排序数组中的重复项](https://github.com/youngyangyang04/leetcode/blob/master/problems/0026.删除排序数组中的重复项.md)
* [19.删除链表的倒数第N个节点](https://github.com/youngyangyang04/leetcode/blob/master/problems/19.删除链表的倒数第N个节点) * [0019.删除链表的倒数第N个节点](https://github.com/youngyangyang04/leetcode/blob/master/problems/19.删除链表的倒数第N个节点)
* [0206.翻转链表](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg) * [0206.翻转链表](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg)
* [0142.环形链表II](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA) * [0142.环形链表II](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA)
* [0344.反转字符串](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA) * [0344.反转字符串](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA)
* [剑指Offer05.替换空格](https://mp.weixin.qq.com/s/t0A9C44zgM-RysAQV3GZpg) * [剑指Offer05.替换空格](https://mp.weixin.qq.com/s/t0A9C44zgM-RysAQV3GZpg)
* [0151.翻转字符串里的单词](https://mp.weixin.qq.com/s/X3qpi2v5RSp08mO-W5Vicw) * [0151.翻转字符串里的单词](https://mp.weixin.qq.com/s/X3qpi2v5RSp08mO-W5Vicw)
* [0977.有序数组的平方](https://github.com/youngyangyang04/leetcode/blob/master/problems/0977.有序数组的平方.md)
* 栈与队列经典题目 * 栈与队列经典题目
@ -191,8 +192,14 @@
* [0225.用队列实现栈](https://github.com/youngyangyang04/leetcode/blob/master/problems/0225.用队列实现栈.md) * [0225.用队列实现栈](https://github.com/youngyangyang04/leetcode/blob/master/problems/0225.用队列实现栈.md)
* [0020.有效的括号](https://github.com/youngyangyang04/leetcode/blob/master/problems/0020.有效的括号.md) * [0020.有效的括号](https://github.com/youngyangyang04/leetcode/blob/master/problems/0020.有效的括号.md)
* [1047.删除字符串中的所有相邻重复项](https://github.com/youngyangyang04/leetcode/blob/master/problems/1047.删除字符串中的所有相邻重复项.md) * [1047.删除字符串中的所有相邻重复项](https://github.com/youngyangyang04/leetcode/blob/master/problems/1047.删除字符串中的所有相邻重复项.md)
* [0239.滑动窗口最大](https://github.com/youngyangyang04/leetcode/blob/master/problems/0239.滑动窗口最大值.md) * [0150.逆波兰表达式求](https://github.com/youngyangyang04/leetcode/blob/master/problems/0150.逆波兰表达式求值.md)
* [0347.前K个高频元素](https://github.com/youngyangyang04/leetcode/blob/master/problems/0347.前K个高频元素.md) * [0347.前K个高频元素](https://github.com/youngyangyang04/leetcode/blob/master/problems/0347.前K个高频元素.md)
* 单调队列
* [0239.滑动窗口最大值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0239.滑动窗口最大值.md)
* 单调栈
* [0739.每日温度](https://github.com/youngyangyang04/leetcode/blob/master/problems/0739.每日温度.md)
* [0042.接雨水](https://github.com/youngyangyang04/leetcode/blob/master/problems/0042.接雨水.md)
* [0084.柱状图中最大的矩形](https://github.com/youngyangyang04/leetcode/blob/master/problems/0084.柱状图中最大的矩形.md)
* 二叉树经典题目 * 二叉树经典题目
* [0144.二叉树的前序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0144.二叉树的前序遍历.md) * [0144.二叉树的前序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0144.二叉树的前序遍历.md)
@ -288,6 +295,7 @@
|[0143.重排链表](https://github.com/youngyangyang04/leetcode/blob/master/problems/0143.重排链表.md) |链表 |中等|**快慢指针/双指针** 也可以用数组,双向队列模拟,考察链表综合操作的好题| |[0143.重排链表](https://github.com/youngyangyang04/leetcode/blob/master/problems/0143.重排链表.md) |链表 |中等|**快慢指针/双指针** 也可以用数组,双向队列模拟,考察链表综合操作的好题|
|[0144.二叉树的前序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0144.二叉树的前序遍历.md) |树 |中等|**递归** **迭代/栈**| |[0144.二叉树的前序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0144.二叉树的前序遍历.md) |树 |中等|**递归** **迭代/栈**|
|[0145.二叉树的后序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0145.二叉树的后序遍历.md) |树 |困难|**递归** **迭代/栈**| |[0145.二叉树的后序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0145.二叉树的后序遍历.md) |树 |困难|**递归** **迭代/栈**|
|[0150.逆波兰表达式求值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0150.逆波兰表达式求值.md) |栈 |中等|**栈**|
|[0151.翻转字符串里的单词](https://github.com/youngyangyang04/leetcode/blob/master/problems/0151.翻转字符串里的单词.md) |字符串 |中等|**模拟/双指针**| |[0151.翻转字符串里的单词](https://github.com/youngyangyang04/leetcode/blob/master/problems/0151.翻转字符串里的单词.md) |字符串 |中等|**模拟/双指针**|
|[0155.最小栈](https://github.com/youngyangyang04/leetcode/blob/master/problems/0155.最小栈.md) |栈 |简单|**栈**| |[0155.最小栈](https://github.com/youngyangyang04/leetcode/blob/master/problems/0155.最小栈.md) |栈 |简单|**栈**|
|[0199.二叉树的右视图](https://github.com/youngyangyang04/leetcode/blob/master/problems/0199.二叉树的右视图.md) |二叉树 |中等|**广度优先遍历/队列**| |[0199.二叉树的右视图](https://github.com/youngyangyang04/leetcode/blob/master/problems/0199.二叉树的右视图.md) |二叉树 |中等|**广度优先遍历/队列**|
@ -323,6 +331,7 @@
|[0459.重复的子字符串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0459.重复的子字符串.md) |字符创 |简单| **KMP**| |[0459.重复的子字符串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0459.重复的子字符串.md) |字符创 |简单| **KMP**|
|[0486.预测赢家](https://github.com/youngyangyang04/leetcode/blob/master/problems/0486.预测赢家.md) |动态规划 |中等| **递归** **记忆递归** **动态规划**| |[0486.预测赢家](https://github.com/youngyangyang04/leetcode/blob/master/problems/0486.预测赢家.md) |动态规划 |中等| **递归** **记忆递归** **动态规划**|
|[0491.递增子序列](https://github.com/youngyangyang04/leetcode/blob/master/problems/0491.递增子序列.md) |深度优先搜索 |中等|**深度优先搜索/回溯算法**| |[0491.递增子序列](https://github.com/youngyangyang04/leetcode/blob/master/problems/0491.递增子序列.md) |深度优先搜索 |中等|**深度优先搜索/回溯算法**|
|[0496.下一个更大元素I](https://github.com/youngyangyang04/leetcode/blob/master/problems/0496.下一个更大元素I.md) |栈 |中等|**单调栈** 入门题目,但是两个数组还是有点绕的|
|[0501.二叉搜索树中的众数](https://github.com/youngyangyang04/leetcode/blob/master/problems/0501.二叉搜索树中的众数.md) |二叉树 |简单|**递归/中序遍历**| |[0501.二叉搜索树中的众数](https://github.com/youngyangyang04/leetcode/blob/master/problems/0501.二叉搜索树中的众数.md) |二叉树 |简单|**递归/中序遍历**|
|[0513.找树左下角的值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0513.找树左下角的值.md) |二叉树 |中等|**递归** **迭代**| |[0513.找树左下角的值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0513.找树左下角的值.md) |二叉树 |中等|**递归** **迭代**|
|[0515.在每个树行中找最大值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0515.在每个树行中找最大值.md) |二叉树 |简单|**广度优先搜索/队列**| |[0515.在每个树行中找最大值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0515.在每个树行中找最大值.md) |二叉树 |简单|**广度优先搜索/队列**|
@ -343,9 +352,11 @@
|[0701.二叉搜索树中的插入操作](https://github.com/youngyangyang04/leetcode/blob/master/problems/0701.二叉搜索树中的插入操作.md) |树 |简单|**递归** **迭代**| |[0701.二叉搜索树中的插入操作](https://github.com/youngyangyang04/leetcode/blob/master/problems/0701.二叉搜索树中的插入操作.md) |树 |简单|**递归** **迭代**|
|[0705.设计哈希集合](https://github.com/youngyangyang04/leetcode/blob/master/problems/0705.设计哈希集合.md) |哈希表 |简单|**模拟**| |[0705.设计哈希集合](https://github.com/youngyangyang04/leetcode/blob/master/problems/0705.设计哈希集合.md) |哈希表 |简单|**模拟**|
|[0707.设计链表](https://github.com/youngyangyang04/leetcode/blob/master/problems/0707.设计链表.md) |链表 |中等|**模拟**| |[0707.设计链表](https://github.com/youngyangyang04/leetcode/blob/master/problems/0707.设计链表.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**| |[0841.钥匙和房间](https://github.com/youngyangyang04/leetcode/blob/master/problems/0841.钥匙和房间.md) |孤岛问题 |中等|**bfs** **dfs**|
|[0844.比较含退格的字符串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0844.比较含退格的字符串.md) |字符串 |简单|**栈** **双指针优化** 使用栈的思路但没有必要使用栈| |[0844.比较含退格的字符串](https://github.com/youngyangyang04/leetcode/blob/master/problems/0844.比较含退格的字符串.md) |字符串 |简单|**栈** **双指针优化** 使用栈的思路但没有必要使用栈|
|[0977.有序数组的平方](https://github.com/youngyangyang04/leetcode/blob/master/problems/0977.有序数组的平方.md) |数组 |中等|**双指针**| |[0925.长按键入](https://github.com/youngyangyang04/leetcode/blob/master/problems/0925.长按键入.md) |字符串 |简单|**双指针/模拟** 是一道模拟类型的题目|
|[0977.有序数组的平方](https://github.com/youngyangyang04/leetcode/blob/master/problems/0977.有序数组的平方.md) |数组 |中等|**双指针** 还是比较巧妙的|
|[1002.查找常用字符](https://github.com/youngyangyang04/leetcode/blob/master/problems/1002.查找常用字符.md) |栈 |简单|**栈**| |[1002.查找常用字符](https://github.com/youngyangyang04/leetcode/blob/master/problems/1002.查找常用字符.md) |栈 |简单|**栈**|
|[1047.删除字符串中的所有相邻重复项](https://github.com/youngyangyang04/leetcode/blob/master/problems/1047.删除字符串中的所有相邻重复项.md) |哈希表 |简单|**哈希表/数组**| |[1047.删除字符串中的所有相邻重复项](https://github.com/youngyangyang04/leetcode/blob/master/problems/1047.删除字符串中的所有相邻重复项.md) |哈希表 |简单|**哈希表/数组**|
|[剑指Offer05.替换空格](https://github.com/youngyangyang04/leetcode/blob/master/problems/剑指Offer05.替换空格.md) |字符串 |简单|**双指针**| |[剑指Offer05.替换空格](https://github.com/youngyangyang04/leetcode/blob/master/problems/剑指Offer05.替换空格.md) |字符串 |简单|**双指针**|

BIN
pics/925.长按键入.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -41,7 +41,6 @@ public:
本题是从栈底到栈头 从小到大,和 接雨水正好反过来。 本题是从栈底到栈头 从小到大,和 接雨水正好反过来。
``` ```
class Solution { class Solution {
public: public:

View File

@ -0,0 +1,38 @@
## 思路
要考率 和 普通数组转成二叉树有什么差别
注意这里是构造平衡二叉搜索树,其实 这里不用强调,因为数组构造二叉树,构成平衡树是自然而然的事情,因为大家默认都是从中间取值,不可能随机取,自找麻烦
一想 这道题目还是有难度的,
一定是递归 分治
循环不变量 的题目列表
注意答案不是唯一的
输入:[-10,-3,0,5,9]
输出:[0,-10,5,null,-3,null,9]
预期结果:[0,-3,9,-10,null,5]
```
class Solution {
private:
TreeNode* traversal(vector<int>& nums, int left, int right) {
if (left > right) return nullptr;
int mid = (left + right) / 2; // 注意越界
TreeNode* root = new TreeNode(nums[mid]);
root->left = traversal(nums, left, mid - 1);
root->right = traversal(nums, mid + 1, right);
return root;
}
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
TreeNode* root = traversal(nums, 0, nums.size() - 1);
return root;
}
};
```

View File

@ -137,6 +137,8 @@ public:
}; };
``` ```
### 普通二叉树的删除方式
这里我在介绍一种通用的删除,普通二叉树的删除方式(没有使用搜索树的特性,遍历整棵树),用交换值的操作来删除目标节点。 这里我在介绍一种通用的删除,普通二叉树的删除方式(没有使用搜索树的特性,遍历整棵树),用交换值的操作来删除目标节点。
代码中目标节点(要删除的节点)被操作了两次: 代码中目标节点(要删除的节点)被操作了两次:

View File

@ -0,0 +1,35 @@
## 链接
https://leetcode-cn.com/problems/next-greater-element-i/
## 思路
两个数组逻辑还是有点绕
最好还是把所有情况列出来
```
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
stack<int> st;
vector<int> result(nums1.size(), -1);
if (nums1.size() == 0) return result;
unordered_map<int, int> umap; // key:下表元素value下表
for (int i = 0; i < nums1.size(); i++) {
umap[nums1[i]] = i;
}
st.push(0);
for (int i = 1; i < nums2.size(); i++) {
while (!st.empty() && nums2[i] > nums2[st.top()]) {
if (umap.count(nums2[st.top()]) > 0) { // 看map里是否存在这个元素
int index = umap[nums2[st.top()]]; // 根据map找到nums2[st.top()] 在 nums1中的下表
result[index] = nums2[i];
}
st.pop();
}
st.push(i);
}
return result;
}
};
```

View File

@ -0,0 +1,62 @@
## 链接
https://leetcode-cn.com/problems/next-greater-element-ii/
## 思路
可以把两个数组拼接在一起
代码性能不行啊,得找找优化的方式
```
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
vector<int> nums1(nums.begin(), nums.end());
nums.insert(nums.end(), nums1.begin(), nums1.end());
vector<int> result(nums.size(), -1);
if (nums.size() == 0) return result;
stack<int> st;
st.push(0);
for (int i = 0; i < nums.size(); i++) {
while (!st.empty() && nums[i] > nums[st.top()]) {
result[st.top()] = nums[i];
st.pop();
}
st.push(i);
}
result.resize(nums.size() / 2);
return result;
}
};
```
这样好像能高一些
```
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
vector<int> nums1(nums.begin(), nums.end());
nums.resize(nums.size() * 2);
int h = nums.size() / 2;
for (int i = 0; i < nums.size() / 2; i++) {
nums[h + i] = nums[i];
}
//nums.insert(nums.end(), nums1.begin(), nums1.end());
vector<int> result(nums.size(), -1);
if (nums.size() == 0) return result;
stack<int> st;
st.push(0);
for (int i = 0; i < nums.size(); i++) {
while (!st.empty() && nums[i] > nums[st.top()]) {
result[st.top()] = nums[i];
st.pop();
}
st.push(i);
}
result.resize(nums.size() / 2);
return result;
}
};
```

View File

@ -1,8 +1,16 @@
## 题目链接
https://leetcode-cn.com/problems/trim-a-binary-search-tree/
> 如果不对递归有深刻的理解,本题有点难 > 如果不对递归有深刻的理解,本题有点难
> 单纯移除一个节点那还不够,要修剪!
# 669. 修剪二叉搜索树 # 669. 修剪二叉搜索树
题目链接https://leetcode-cn.com/problems/trim-a-binary-search-tree/
给定一个二叉搜索树同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。 给定一个二叉搜索树同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。
![669.修剪二叉搜索树](https://img-blog.csdnimg.cn/20201014173115788.png) ![669.修剪二叉搜索树](https://img-blog.csdnimg.cn/20201014173115788.png)
@ -11,11 +19,13 @@
# 思路 # 思路
相信看到这道题目大家都感觉是一道简单题事实上leetcode上也明是简单)。 相信看到这道题目大家都感觉是一道简单题事实上leetcode上也明是简单)。
但还真的不简单!
## 递归法 ## 递归法
直接想法就是:递归处理,然后遇到 `root->val < low || root->val > high` 的时候直接return NULL一波修,赶紧利落。 直接想法就是:递归处理,然后遇到 `root->val < low || root->val > high` 的时候直接return NULL一波修,赶紧利落。
不难写出如下代码: 不难写出如下代码:
@ -31,7 +41,7 @@ public:
}; };
``` ```
**然而[1, 3]区间在二叉搜索树的中可不是单纯的节点3和左孩子节点0就决定的还要考虑节点0的右子树** **然而[1, 3]区间在二叉搜索树的中可不是单纯的节点3和左孩子节点0就决定的还要考虑节点0的右子树**
我们在重新关注一下第二个示例,如图: 我们在重新关注一下第二个示例,如图:
@ -43,7 +53,7 @@ public:
其实不用重构那么复杂。 其实不用重构那么复杂。
在上图中我们发现节点0并不符合区间要求那么将节点0的右孩子 节点2 直接赋给 节点3的左孩子就可以了就是把元素0减掉),如图: 在上图中我们发现节点0并不符合区间要求那么将节点0的右孩子 节点2 直接赋给 节点3的左孩子就可以了就是把节点0从二叉树中移除),如图:
<img src='../pics/669.修剪二叉搜索树1.png' width=600> </img></div> <img src='../pics/669.修剪二叉搜索树1.png' width=600> </img></div>
@ -52,14 +62,13 @@ public:
* 确定递归函数的参数以及返回值 * 确定递归函数的参数以及返回值
首先**我们要返回函数参数节点root为根节点的树 修剪完之后的 新的根节点**这里我们为什么需要返回值呢? 这里我们为什么需要返回值呢?
因为是要遍历整棵树,做修改,其实不需要返回值也可以,我们也可以完成修剪(其实就是从二叉树中移除节点)的操作。
因为是要遍历整棵树,做修改,其实不需要返回值也可以,我们也可以完成修剪(其实就是要删除节点)的操作 但是有返回值,更方便,可以通过递归函数的返回值来移除节点
但是有返回值,更方便,可以通过 这样的赋值语句:`root->left = trimBST(root->left, int low, int high)` 直接删除root的左孩子如果root的左孩子不在范围内的话 这样的做法在[二叉树:搜索树中的插入操作](https://mp.weixin.qq.com/s/lwKkLQcfbCNX2W-5SOeZEA)和[二叉树:搜索树中的删除操作](https://mp.weixin.qq.com/s/-p-Txvch1FFk3ygKLjPAKw)中大家已经了解过了
**因为`trimBST(root->left, int low, int high)` 将返回当前root左子树以root->left为根节点的二叉树修剪完之后的新的根节点。**
代码如下: 代码如下:
@ -77,7 +86,7 @@ if (root == nullptr ) return nullptr;
* 确定单层递归的逻辑 * 确定单层递归的逻辑
如果root当前节点的元素小于low的数值那么应该递归右子树并返回右子树的头结点。 如果root当前节点的元素小于low的数值那么应该递归右子树并返回右子树符合条件的头结点。
代码如下: 代码如下:
@ -88,7 +97,7 @@ if (root->val < low) {
} }
``` ```
如果root(当前节点)的元素小于high的那么应该递归左子树并返回左子树的头结点。 如果root(当前节点)的元素小于high的那么应该递归左子树并返回左子树符合条件的头结点。
代码如下: 代码如下:
@ -99,33 +108,43 @@ if (root->val > high) {
} }
``` ```
接下来要将处理完左子树的结果赋给root->left处理完右子树的结果赋给root->right。 接下来要将下一层处理完左子树的结果赋给root->left处理完右子树的结果赋给root->right。
最后返回root节点代码如下 最后返回root节点代码如下
``` ```
root->left = trimBST(root->left, low, high); // root->left接入符合条件的左孩子 root->left = trimBST(root->left, low, high); // root->left接入符合条件的左孩子
root->right = trimBST(root->right, low, high); // root->right接入符合条件的右孩子 root->right = trimBST(root->right, low, high); // root->right接入符合条件的右孩子
return root; return root;
``` ```
此时大家是不是还没发现这多余的节点究竟是如何除的? 此时大家是不是还没发现这多余的节点究竟是如何从二叉树中移除的
在回顾一下上面的代码,针对下图中二叉树的情况:
<img src='../pics/669.修剪二叉搜索树1.png' width=600> </img></div>
如下代码相当于把节点0的右孩子节点2返回给上一层
```
if (root->val < low) {
TreeNode* right = trimBST(root->right, low, high); // 寻找符合区间[low, high]的节点
return right;
}
```
然后如下代码相当于用节点3的左孩子 把下一层返回的 节点0的右孩子节点2 接住。
其实就是通过,这两个语句删除的。
``` ```
root->left = trimBST(root->left, low, high); root->left = trimBST(root->left, low, high);
root->right = trimBST(root->right, low, high);
``` ```
root重新规划root的左右孩子究竟是谁拿图中示例为例此时root为节点3那么trimBST(root->left, low, high)返回的就是节点2`root->left = trimBST(root->left, low, high);` 相当于把节点0删除了。 此时节点3的右孩子就变成了节点2将节点0从二叉树中移除了。
最后整体代码如下: 最后整体代码如下:
``` ```
class Solution { class Solution {
public: public:
// 注意这里是返回该树的头结点
TreeNode* trimBST(TreeNode* root, int low, int high) { TreeNode* trimBST(TreeNode* root, int low, int high) {
if (root == nullptr ) return nullptr; if (root == nullptr ) return nullptr;
if (root->val < low) { if (root->val < low) {
@ -159,6 +178,8 @@ public:
}; };
``` ```
只看代码,其实不太好理解节点是符合移除的,这一块大家可以自己在模拟模拟!
## 迭代法 ## 迭代法
因为二叉搜索树的有序性,不需要使用栈模拟递归的过程。 因为二叉搜索树的有序性,不需要使用栈模拟递归的过程。
@ -212,6 +233,6 @@ public:
**如果不对递归有深刻的理解,这道题目还是有难度的!** **如果不对递归有深刻的理解,这道题目还是有难度的!**
本题我依然给出递归法和迭代法,大家只要掌握递归其实就可以了,如果想进一步学习,就把迭代法也写一写。 本题我依然给出递归法和迭代法,初学者掌握递归就可以了,如果想进一步学习,就把迭代法也写一写。
**就酱,如果学到了,就转发给身边需要的同学吧!** **就酱,如果学到了,就转发给身边需要的同学吧!**

View File

@ -0,0 +1,53 @@
# 思路
使用递减栈(从大到小 栈底到栈头)
```
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& T) {
// 递减栈
stack<int> st;
vector<int> result(T.size(), 0);
st.push(0);
for (int i = 1; i < T.size(); i++) {
if (T[i] < T[st.top()]) { // 把i放入栈
st.push(i);
} else if (T[i] == T[st.top()]) { // 相同也要把i放进去例如 1 1 1 1 2
st.push(i);
} else {
while (!st.empty() && T[i] > T[st.top()]) { // 注意栈不能为空
result[st.top()] = i - st.top();
st.pop();
}
st.push(i);
}
}
return result;
}
};
```
建议一开始 都把每种情况分析好,不要上来看简短的代码,关键逻辑都被隐藏了。
精简代码如下:
```
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& T) {
stack<int> st; // 递减栈
vector<int> result(T.size(), 0);
st.push(0);
for (int i = 1; i < T.size(); i++) {
while (!st.empty() && T[i] > T[st.top()]) { // 注意栈不能为空
result[st.top()] = i - st.top();
st.pop();
}
st.push(i);
}
return result;
}
};
```

View File

@ -0,0 +1,59 @@
## 思路
这道题目一看以为是哈希,仔细一看不行,要有顺序。
所以模拟同时遍历两个数组,进行对比就可以了。
对比的时候需要一下几点:
* name[i] 和 typed[j]相同则i++j++ (继续向后对比)
* name[i] 和 typed[j]不相同
* 看是不是第一位就不相同了也就是j如果等于0那么直接返回false
* 不是第一位不相同就让j跨越重复项移动到重复项之后的位置再次比较name[i] 和typed[j]
* 如果 name[i] 和 typed[j]相同则i++j++ (继续向后对比)
* 不相同返回false
* 对比完之后有两种情况
* name没有匹配完例如name:"pyplrzzzzdsfa" type:"ppyypllr"
* type没有匹配完例如name:"alex" type:"alexxrrrrssda"
动画如下:
<img src='../video/925.长按键入.gif' width=600> </img></div>
上面的逻辑想清楚了不难写出如下C++代码:
```
class Solution {
public:
bool isLongPressedName(string name, string typed) {
int i = 0, j = 0;
while (i < name.size() && j < typed.size()) {
if (name[i] == typed[j]) { // 相同则同时向后匹配
j++; i++;
} else { // 不相同
if (j == 0) return false; // 如果是第一位就不相同直接返回false
// j跨越重复项向后移动同时防止j越界
while(j < typed.size() && typed[j] == typed[j - 1]) j++;
if (name[i] == typed[j]) { // j跨越重复项之后再次和name[i]匹配
j++; i++; // 相同则同时向后匹配
}
else return false;
}
}
// 说明name没有匹配完例如 name:"pyplrzzzzdsfa" type:"ppyypllr"
if (i < name.size()) return false;
// 说明type没有匹配完例如 name:"alex" type:"alexxrrrrssda"
while (j < typed.size()) {
if (typed[j] == typed[j - 1]) j++;
else return false;
}
return true;
}
};
```
时间复杂度O(n)
空间复杂度O(1)

BIN
video/925.长按键入.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 940 KiB