513.找树左下角的值
先复习了一遍层序遍历。
class Solution {
public:
int bottomLeft=0; //最后一个结点的值
int max_depth = INT_MIN;
void traversal(TreeNode* cur, int depth){
if (cur->left == nullptr && cur->right == nullptr){
if (depth > max_depth){
max_depth = depth;
bottomLeft = cur->val;
return ; //递归终止条件,找到最深度的叶子结点;由于左右都会遍历,最后停止递归时肯定是最是深度的那个。
}
}
if (cur->left){
depth++;
traversal(cur->left, depth);
depth--; //回溯
}
if (cur->right){
depth++;
traversal(cur->right, depth);
depth--; //回溯
}
}
int findBottomLeftValue(TreeNode* root) {
traversal(root, 0);
return bottomLeft;
}
};
犯的错误:将 int max_depth = INT_MIN;放在了traversal()中遍历;这会导致每次递归max_depth 都会被更新致使每次遍历都会更新结果bottomLeft。
112. 路径总和
class Solution {
public:
bool traversal (TreeNode* cur, int count){
if (!cur->left && !cur->right && count==0) return true; //判断该根-叶的路径上的值总和是否等于count
if (!cur->left && !cur->right) return false;
if (cur->left){
count-=cur->left->val; //处理count的值先于判断count的值
if (traversal(cur->left, count)) return true; //将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; //遍历完根结点的左右孩子,如果没有返回true则返回false
}
bool hasPathSum(TreeNode* root, int targetSum) {
if (!root) return false;
int count = targetSum;
count-=root->val; //先处理count的值
return traversal(root, targetSum - root->val);
}
};
值得注意的点:
1、对count的处理顺序,先减去当前节点的值,之后判断其子节点是否能将count减完,之后回溯。
即这个过程
count-=cur->left->val; //处理count的值先于判断count的值
if (traversal(cur->left, count)) return true; //将true层层上传
count+=cur->left->val; //回溯
每次传入traversal需要继续被减的都是减去当前节点的值。
113.路径总和ii
class Solution {
public:
vector<vector<int>> result;
vector<int> path;
void traversal(TreeNode* cur, int count){
path.push_back(cur->val);
if (cur->left==nullptr && cur->right==nullptr) {
if (count==0) {//所有根-叶并且值总和等于给定值的路径,加入result
result.push_back(path);
return;
}
return;
}
if (cur->left){
count -= cur->left->val;
traversal(cur->left, count);
path.pop_back();
count += cur->left->val;
}
if (cur->right){
count -= cur->right->val;
traversal(cur->right, count);
path.pop_back();//回溯1
count += cur->right->val;//回溯2
}
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
result.clear();
path.clear();
if (!root) return result;
targetSum-=root->val;
traversal(root, targetSum);
return result;
}
};
和卡哥写的略微不同,我的写法和之前那道求所有路径类似。 path.push_back(cur->val);放在遍历的最前面。其他的和上道题思路类似,先处理当前节点的值再计算还需要减去的部分。
106.从中序与后序遍历序列构造二叉树
通过后序找中间节点,用于切割中序数组。
class Solution {
public:
TreeNode* traversal(vector<int>& inorder, vector<int>& postorder){
if (postorder.size()==0) return nullptr;
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> leftInorder(inorder.begin(), inorder.begin() + delimiterIndex);
//[delimiterIndex, end)
vector<int> rightInorder(inorder.begin() + delimiterIndex+1, inorder.end());
postorder.resize(postorder.size()-1);
// [0, leftInorder.size)
vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
// [leftInorder.size(), end)
vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());
root->left = traversal(leftInorder, leftPostorder);
root->right = traversal(rightInorder, rightPostorder);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (inorder.size() == 0 || postorder.size() == 0) return NULL;
return traversal(inorder, postorder);
}
};
注意:必须要有中序序列才能确定一棵二叉树,因为中序将二叉树的左右子树隔开。