From ff4aaefd9dc011dce8ccc16288837857d1591ef0 Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Sat, 1 Aug 2020 11:38:32 +0800 Subject: [PATCH] Update --- README.md | 5 +- problems/0098.验证二叉搜索树.md | 64 +++++++++++++ problems/0225.用队列实现栈.md | 2 +- problems/0226.翻转二叉树.md | 23 +++++ problems/0617.合并二叉树.md | 119 +++++++++++++++++++++++++ problems/0654.最大二叉树.md | 44 +++++++++ 6 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 problems/0098.验证二叉搜索树.md create mode 100644 problems/0226.翻转二叉树.md create mode 100644 problems/0617.合并二叉树.md create mode 100644 problems/0654.最大二叉树.md diff --git a/README.md b/README.md index 8ffb5ab1..4a40a252 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ |[0059.螺旋矩阵II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0059.螺旋矩阵II.md) |数组 |中等|**模拟**| |[0083.删除排序链表中的重复元素](https://github.com/youngyangyang04/leetcode/blob/master/problems/0083.删除排序链表中的重复元素.md) |链表 |简单|**模拟**| |[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) |树 |简单|**递归** **迭代/队列/栈**| |[0104.二叉树的最大深度](https://github.com/youngyangyang04/leetcode/blob/master/problems/0104.二叉树的最大深度.md) |树 |简单|**递归** **队列/BFS**| @@ -67,7 +68,9 @@ |[0383.赎金信](https://github.com/youngyangyang04/leetcode/blob/master/problems/0383.赎金信.md) |数组 |简单|**暴力** **字典计数** **哈希**| |[0434.字符串中的单词数](https://github.com/youngyangyang04/leetcode/blob/master/problems/0434.字符串中的单词数.md) |字符串 |简单|**模拟**| |[0454.四数相加II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0454.四数相加II.md) |哈希表 |中等| **哈希**| -|[0575.分糖果.md](https://github.com/youngyangyang04/leetcode/blob/master/problems/0575.分糖果.md) |哈希表 |简单|**哈希**| +|[0575.分糖果](https://github.com/youngyangyang04/leetcode/blob/master/problems/0575.分糖果.md) |哈希表 |简单|**哈希**| +|[0617.合并二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0617.合并二叉树.md) |树 |简单|**递归** **迭代**| +|[0654.最大二叉树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0654.最大二叉树.md) |树 |中等|**递归**| |[0705.设计哈希集合](https://github.com/youngyangyang04/leetcode/blob/master/problems/0705.设计哈希集合.md) |哈希表 |简单|**模拟**| |[0707.设计链表](https://github.com/youngyangyang04/leetcode/blob/master/problems/0707.设计链表.md) |链表 |中等|**模拟**| |[1047.删除字符串中的所有相邻重复项](https://github.com/youngyangyang04/leetcode/blob/master/problems/1047.删除字符串中的所有相邻重复项.md) |栈 |简单|**栈**| diff --git a/problems/0098.验证二叉搜索树.md b/problems/0098.验证二叉搜索树.md new file mode 100644 index 00000000..fcdd2611 --- /dev/null +++ b/problems/0098.验证二叉搜索树.md @@ -0,0 +1,64 @@ +## 题目地址 + +## 思路 + +这道题目比较容易陷入两个陷阱: +* 陷阱1 :[10,5,15,null,null,6,20] 这个case 要考虑道 +* 陷阱2:样例中根节点的val 可能是-2147483648 + +中序遍历之后 输出的顺序就应该是一个从大到小的顺序, 可以使用一个全局变量进行比较。 + +## C++代码 + + +[10,5,15,null,null,6,20] 为什么预期结果是 false.... 这是经典陷阱 +错误代码 +``` +class Solution { +public: + bool isValidBST(TreeNode* root) { + if (root == NULL) return true; + + if (root->left != NULL && root->right != NULL) { + if (root->val > root->left->val && root->val < root->right->val) { + return true; + } else { + return false; + } + } + + if (root->left != NULL && root->right == NULL) { + if (root->val > root->left->val) { + return true; + }else { + return false; + } + } + if (root->left == NULL && root->right != NULL) { + if (root->val < root->right->val) { + return true; + }else { + return false; + } + } + if (root->left == NULL && root->right == NULL) return true; + return isValidBST(root->left) && isValidBST(root->right); + } +}; +``` + +正确代码 +``` +class Solution { +public: + long long val = LONG_MIN; + bool isValidBST(TreeNode* root) { + if (root == NULL) return true; + bool left = isValidBST(root->left); + if (val < root->val) val = root->val;// 中序遍历,这里相当于从大到小进行比较 + else return false; + bool right = isValidBST(root->right); + return left && right; + } +}; +``` diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md index dbf45fab..42a275d8 100644 --- a/problems/0225.用队列实现栈.md +++ b/problems/0225.用队列实现栈.md @@ -58,5 +58,5 @@ public: } }; ``` -> 更过算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。 +> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。 diff --git a/problems/0226.翻转二叉树.md b/problems/0226.翻转二叉树.md new file mode 100644 index 00000000..f5fbc836 --- /dev/null +++ b/problems/0226.翻转二叉树.md @@ -0,0 +1,23 @@ +## 题目地址 +https://leetcode-cn.com/problems/invert-binary-tree/ + +## 思路 + +递归的过程,交换左右节点。 + +## C++代码 + +``` +class Solution { +public: + TreeNode* invertTree(TreeNode* root) { + if (root == NULL) return root; + swap(root->left, root->right); + invertTree(root->left); + invertTree(root->right); + return root; + } +}; +``` + +> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。 diff --git a/problems/0617.合并二叉树.md b/problems/0617.合并二叉树.md new file mode 100644 index 00000000..7c95c2bb --- /dev/null +++ b/problems/0617.合并二叉树.md @@ -0,0 +1,119 @@ +## 题目地址 +https://leetcode-cn.com/problems/merge-two-binary-trees/ + +## 思路 + +四种写法,总有一款适合你,其实这道题目迭代法实现是比较困难的,大家可以试一试,是一道不错的面试进阶题目。 + +四种写法如下: + +1. 递归修改了输入树的结构 +2. 递归不修改树的结构 +3. 递归,一波指针的操作,自己写的野路子(可以用来深度理解一下C++的指针) +4. 迭代(这应该是最简单直观的迭代法代码了,一看就懂) + +## C++代码 + +### 递归 + +修改了输入树的结构 +``` +class Solution { +public: + TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { + if (t1 == NULL) return t2; + if (t2 == NULL) return t1; + t1->val += t2->val; + t1->left = mergeTrees(t1->left, t2->left); + t1->right = mergeTrees(t1->right, t2->right); + return t1; + } +}; +``` + +不修改输入树的结构 +``` +class Solution { +public: + TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { + if (t1 == NULL) return t2; + if (t2 == NULL) return t1; + TreeNode* root = new TreeNode(0); + root->val = t1->val + t2->val; + root->left = mergeTrees(t1->left, t2->left); + root->right = mergeTrees(t1->right, t2->right); + return root; + } +}; +``` + +一波指针的操作,自己写的野路子 +想要更改二叉树的值,应该传入指向指针的指针, 如果process(t1, t2);这么写的话,其实只是传入的一个int型的指针,并没有传入地址,要传入指向指针的指针才能完成对t1的修改。 +``` +class Solution { +public: + void process(TreeNode** t1, TreeNode** t2) { + if ((*t1) == NULL && (*t2) == NULL) return; + if ((*t1) != NULL && (*t2) != NULL) { + (*t1)->val += (*t2)->val; + } + if ((*t1) == NULL && (*t2) != NULL) { + *t1 = *t2; + return; + } + if ((*t1) != NULL && (*t2) == NULL) { + return; + } + process(&((*t1)->left), &((*t2)->left)); + process(&((*t1)->right), &((*t2)->right)); + } + TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { + process(&t1, &t2); + return t1; + } +}; +``` +### 迭代 + +这应该是最简单直观的迭代法了 +``` +class Solution { +public: + TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { + if (t1 == NULL) return t2; + if (t2 == NULL) return t1; + queue que; + que.push(t1); + que.push(t2); + while(!que.empty()) { + TreeNode* node1 = que.front(); que.pop(); + TreeNode* node2 = que.front(); que.pop(); + // 两个节点不为空,val相加 + if (node1 != NULL && node2 != NULL) { + node1->val += node2->val; + } + // 如果左节点都不为空,加入队列 + if (node1->left != NULL && node2->left != NULL) { + que.push(node1->left); + que.push(node2->left); + } + // 如果右节点都不为空,加入队列 + if (node1->right != NULL && node2->right != NULL) { + que.push(node1->right); + que.push(node2->right); + } + // 当t1的左节点 为空 t2左节点不为空,就赋值过去 + if (node1->left == NULL && node2->left != NULL) { + node1->left = node2->left; + } + // 当t1的右节点 为空 t2右节点不为空,就赋值过去 + if (node1->right == NULL && node2->right != NULL) { + node1->right = node2->right; + } + } + return t1; + } +}; +``` + +> 更多算法干货文章持续更新,可以微信搜索「代码随想录」第一时间围观,关注后,回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等,就可以获得我多年整理的学习资料。 diff --git a/problems/0654.最大二叉树.md b/problems/0654.最大二叉树.md new file mode 100644 index 00000000..f497392d --- /dev/null +++ b/problems/0654.最大二叉树.md @@ -0,0 +1,44 @@ +## 题目地址 +https://leetcode-cn.com/problems/maximum-binary-tree/ + +## 思路 + +典型的递归问题 + +1. 每一层要返回上一层什么内容 +2. 明确终止条件是什么,明确了返回内容,才知道终止条件要返回什么 +3. 每一层的处理条件 + + +## C++代码 + +``` +class Solution { +public: + TreeNode* constructMaximumBinaryTree(vector& nums) { + TreeNode* node = new TreeNode(0); + if (nums.size() == 1) { + node->val = nums[0]; + return node; + } + int maxValue = 0; + int maxValueIndex = 0; + for (int i = 0; i < nums.size(); i++) { + if (nums[i] > maxValue) { + maxValue = nums[i]; + maxValueIndex = i; + } + } + node->val = maxValue; + if (maxValueIndex > 0) { + vector newVec(nums.begin(), nums.begin() + maxValueIndex); + node->left = constructMaximumBinaryTree(newVec); + } + if (maxValueIndex < (nums.size() - 1)) { + vector newVec(nums.begin() + maxValueIndex + 1, nums.end()); + node->right = constructMaximumBinaryTree(newVec); + } + return node; + } +}; +```