513-找树左下角的值
题目链接:LeetCode-513
思考:最后层左下角值,左下角不一定是左下角,得先满足最后一行才行,达到深度最大,左下角的值不一定是左孩子,也可以是右孩子,优先遍历左侧就行
方法一:回溯法
class Solution {
public:
int maxLen=INT_MIN;
int maxleftValue;
void traversal(TreeNode* root,int leftLen){
if(root->left == NULL && root->right == NULL){
if(leftLen>maxLen){
maxLen=leftLen;
maxleftValue=root->val;
}
return;
}
if(root->left){
leftLen++;
traversal(root->left,leftLen);
leftLen--;
//以上3行可以直接写成:traversal(root->left,leftLen+1)
}
if(root->right){
leftLen++;
traversal(root->right,leftLen);
leftLen--;
//以上3行可以直接写成:traversal(root->right,leftLen+1)
}
return;
}
int findBottomLeftValue(TreeNode* root) {
traversal(root,0);
return maxleftValue;
}
};
方法二:迭代法
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
if (root != NULL) que.push(root);
int result = 0;
while (!que.empty()) {
int size = que.size();
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
if (i == 0) result = node->val; // 记录最后一行第一个元素
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
}
return result;
}
};
112-路径总和
题目链接:LeetCode-112
思考:找到目标和就return true,前中后遍历顺序都可以,传入根节点和目标值,用count记录目标值,查找路径减去count值,最后值为0代表找到路径返回true。
代码:递归法
class Solution {
private:
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;
}
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(root==NULL) return false;
return traversal(root,targetSum-root->val);
}
};
106-从中序与后序遍历序列构造二叉树
题目链接:LeetCode-106
思考:中序-左根右;后序-左右根;
后序最后一个节点就是根节点,把前序分为左右两个部分;
后序倒数第二个节点还是根节点,看在前序遍历的左边还是右边,一次类推进行遍历。
步骤6步:
- 如果数组大小为零的话,说明是空节点了。
- 如果不为空,那么取后序数组最后一个元素作为节点元素。
- 找到后序数组最后一个元素在中序数组的位置,作为切割点
- 切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
- 切割后序数组,切成后序左数组和后序右数组
- 递归处理左区间和右区间
代码:
class Solution {
private:
TreeNode* traversal(vector<int>& inorder,vector<int>& postorder){
if(postorder.size()==0) return NULL;
// 后序遍历数组最后一个元素,就是当前的中间节点
int rootValue = postorder[postorder.size()-1];
TreeNode* root=new TreeNode(rootValue);
// 叶子节点
if(postorder.size()==1) return root;
// 找到中序遍历的切割点
int delimiterIndex;
for(delimiterIndex=0;delimiterIndex<inorder.size();delimiterIndex++){
if(inorder[delimiterIndex]==rootValue) break;
}
// 切割中序数组
// 左闭右开区间:[0, delimiterIndex)
vector<int> leftIndorder(inorder.begin(),inorder.begin()+delimiterIndex);
vector<int> rightInorder(inorder.begin()+delimiterIndex+1,inorder.end());
// postorder 舍弃末尾元素
postorder.resize(postorder.size()-1);
// 切割后序数组
// 依然左闭右开,注意这里使用了左中序数组大小作为切割点
// [0, leftInorder.size)
vector<int> leftPostorder(postorder.begin(),postorder.begin()+leftIndorder.size());
// [leftInorder.size(), end)
vector<int> rightPostorder(postorder.begin()+leftIndorder.size(),postorder.end());
root->left=traversal(leftIndorder,leftPostorder);
root->right=traversal(rightInorder,rightPostorder);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size()==0||postorder.size()==0) return NULL;
return traversal(inorder,postorder);
}
};