LeetCode 513 找树左下角的值
题目链接:513. 找树左下角的值
做题情况:独立做题目时候一看就想到用层序遍历来做,遍历到最后一层时候记录树左下角的值,不过自己写的层序遍历写了两次遍历,第一次记录层数,第二次遍历来记录树左下角的值,实际上一次就行,用一个变量记录每层的最左边的值,反复层数迭代,然后遍历到最后一层时候这个变量就是树左下角的值,返回即可,我当时ac代码如下,可以根据前面所说做很大优化:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*>que;
que.push(root);
int res1=0;//用res记录层数
while(!que.empty()){
int size=que.size();
res1++;
for(int i=0;i<size;i++){
TreeNode* tmp=que.front();
que.pop();
if(tmp->left)que.push(tmp->left);
if(tmp->right)que.push(tmp->right);
}
}
que.push(root);
int res2=0;
while(!que.empty()){
int size=que.size();
res2++;
for(int i=0;i<size;i++){
TreeNode* tmp=que.front();
que.pop();
if(res2==res1)return tmp->val;
if(tmp->left)que.push(tmp->left);
if(tmp->right)que.push(tmp->right);
}
}
return 0;
}
};
上述只是迭代法,本题的递归写法自己没有写出来,本题目采用递归遍历顺序中任何一种都可以,因为中没有处理逻辑, 只要左在右前面即可把卡哥代码给抄了一遍:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDepth=INT_MIN;
int result;
void traversal(TreeNode* root, int depth){
if(root->left==NULL&&root->right==NULL){
if(depth>maxDepth){
maxDepth=depth;
result=root->val;
}
return;
}
//中
if(root->left){//左
depth++;//深度加一
traversal(root->left, depth);
depth--;//回溯,深度减一
}
if(root->right){//右
depth++;//深度加一
traversal(root->right, depth);
depth--;//回溯,深度减一
}
return;
}
int findBottomLeftValue(TreeNode* root) {
traversal(root, 0);
return result;
}
};
LeetCode 112 路径总和
题目链接:112. 路径总和
做题情况:本题自己做时候知道用递归回溯来解决,可是不能够ac出代码,看完卡哥视频和代码随想录书相关部分后,看到递归三部曲的思考过程,发现实际上也不难,这道题目重点考查递归函数什么时候需要返回值,什么不需要返回值,这点卡哥讲解很清楚,这又是一个技巧性问题,具体ac代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool traversal(TreeNode* cur, int count){
if(!cur->left&&!cur->right&&count==0)return true;
if(!cur->left&&!cur->right)return false;
//没有中的处理逻辑
if(cur->left){//左
count-=cur->left->val;
if(traversal(cur->left,count))return true;
count +=cur->left->val;//回溯
}
if(cur->right){//右
count -= cur->right->val;
if(traversal(cur->right, count))return true;
count +=cur->right->val;//回溯
}
return false;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root==NULL)return false;
return traversal(root, targetSum-root->val);
}
};
上述代码还有更精简的版本,不过不便于理解,本题也可以使用迭代法来解决,栈中存放的元素定义为:pair<TreeNode*, int> pair<节点指针,路径数值>,所有具体的代码参考卡哥所给出的
扩展题目:113. 路径总和II说明了当遍历整棵树时候递归函数不要返回值的情况
LeetCode 106 从中序与后序遍历序列构造二叉树
题目链接:106. 从中序与后序遍历序列构造二叉树
做题情况:本题目自己手动模拟过程还是很简单,不管是中序与后序构造二叉树还是前序和后序构造二叉树,但是想要写出实现代码还是很有难度的,看完卡哥视频和代码随想录书相关部分后,知道需要严格按照卡哥所给的六个步骤来实现以及递归时候遵循循环不变量原则,也要注意所有的元素值都是唯一的,所以可以代码中可以遍历去找切割点,自己把卡哥所给的代码全部抄了一遍,一个版本如下(这里给出是用下标索引写出的代码版本):
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* traversal(vector<int>& inorder, int inorderBegin,int inorderEnd, vector<int>& postorder, int postorderBegin, int postorderEnd){
if(postorderBegin==postorderEnd)return NULL;
int rootValue = postorder[postorderEnd-1];
TreeNode* root=new TreeNode(rootValue);
if(postorderEnd-postorderBegin==1)return root;
int delimiterIndex;
for(delimiterIndex=inorderBegin;delimiterIndex<inorderEnd;delimiterIndex++){
if(inorder[delimiterIndex]==rootValue)break;
}
int leftInorderBegin = inorderBegin;
int lefInoderEnd = delimiterIndex;
int rightInorderBegin = delimiterIndex + 1;
int rightInorderEnd = inorderEnd;
int leftPostorderBegin = postorderBegin;
int leftPostordereEnd = postorderBegin + delimiterIndex - inorderBegin;
int rightPostorderBegin = postorderBegin + (delimiterIndex-inorderBegin);
int rightPostorderEnd = postorderEnd - 1;
root->left =traversal(inorder, leftInorderBegin, lefInoderEnd, postorder, leftPostorderBegin, leftPostordereEnd);
root->right = traversal(inorder, rightInorderBegin, rightInorderEnd, postorder, rightPostorderBegin, rightPostorderEnd);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return traversal(inorder, 0, inorder.size(), postorder, 0, postorder.size());
}
};
这道题目以及105. 从前序与后序遍历序列构造二叉树还是很考察代码实现能力的,后面需要多多复习
今天的后两道题目特别最后一道题目代码实现感觉还是挺难的,自己在做这些题目时候,要慢慢把握二叉树中递归和回溯的解题技巧,慢慢养成那种思考过程,总共花了四个半小时左右。
贵在坚持,加油,共勉