今天的感悟:遇到一般二叉树题,如果没有思路,应该先考虑求高度还是求深度!
这道题如果用iteration(层序遍历)就太trivial了,故略。如果用递归,应该首先判断是不是处在最大深度。如果是,从中选择最左边的即可。
怎么从中选择最左边的呢?设global variable MAX,这样,当最左边的一旦被找到,无论right branch在递归的哪一层,就能立马知道找到了,从而让后续查找失败。
class Solution {
private:
int val;
int MAX;
int findmaxDepth(TreeNode* root){ //2
if(!root) return 0;
int lmax = 1 + findmaxDepth(root->left);
int rmax = 1 + findmaxDepth(root->right);
return max(lmax, rmax);
}
void findValue(TreeNode* root, int cur){
if(!root) return;
if(cur == MAX){
val = root->val;
MAX = -1;
return;
}
if(root->left){
findValue(root->left, cur+1);
}
if(root->right){
findValue(root->right, cur+1);
}
}
public:
int findBottomLeftValue(TreeNode* root) {
MAX = findmaxDepth(root);
val = root->val;
findValue(root, 1);
return val;
}
};
2.Path Sum
这破题还真挺难,做了挺久,交了挺多次的。主要是trivial case太多了,不好搞。
class Solution {
private:
bool res = false;
bool process = false;
void backtracking(TreeNode* root, int target, int sum){
if(!root->left && !root->right) {sum += root->val; process = true;}
if(sum == target && process && !root->left && !root->right) {
res = true;
return;
}
if(root->left){
process = true;
backtracking(root->left, target, sum + root->val);
}
if(root->right){
process = true;
backtracking(root->right, target, sum + root->val);
}
return;
}
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(!root) return false;
backtracking(root, targetSum, 0);
return res;
}
};
…刚刚看了看答案,发现自己就是大笨比。居然会有这么简洁的解决方案…太厉害了
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(!root) return false;
if(!root->left && !root->right && targetSum == root->val) return true;
return hasPathSum(root->left, targetSum - root->val) || hasPathSum(root->right, targetSum - root->val);
}
};
这才是理想的。就是回溯,但是把循环过程写出来了而已。
class Solution {
private:
vector<vector<int>> res;
vector<int> tmp;
void backtracking(TreeNode* root, int sum){
if(!root) return;
// if(sum < root->val) return; 这行不能加,因为有负数情况,手欠了。
if(!root->left && !root->right && sum == root->val){
tmp.push_back(root->val);
res.push_back(tmp);
tmp.pop_back();
return;
}
if(root->left){
tmp.push_back(root->val);
backtracking(root->left, sum-root->val);
tmp.pop_back();
}
if(root->right){
tmp.push_back(root->val);
backtracking(root->right, sum-root->val);
tmp.pop_back();
}
return;
}
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
backtracking(root, targetSum);
return res;
}
};
4.Construct Binary Tree from Inorder and Postorder Traversal
我的想法是对的,但最后没写对,于是照着答案小改了一下,就过了。分三步:
- 找post-order最后一个元素(就是root)
- 在in-order里找这个元素
- 对应在post-order里,左边就是这个root的left branch,右边(包含这个)就是right branch.
class Solution {
private:
int find(vector<int> vec, int target){
for(int i = 0; i < vec.size(); ++i){
if(vec[i] == target) return i;
}
return -1;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size() == 0) return nullptr;
TreeNode* root = new TreeNode(postorder[postorder.size()-1]);
int div = find(inorder, root->val);
vector<int> v1(inorder.begin(), inorder.begin() + div);
vector<int> v3(inorder.begin()+div+1, inorder.end());
postorder.resize(postorder.size()-1);
vector<int> v2(postorder.begin(), postorder.begin() + v1.size());
vector<int> v4(postorder.begin()+v1.size(), postorder.end());
root->left = buildTree(v1, v2);
root->right = buildTree(v3, v4);
return root;
}
};
剩下前序和中序构造树的题找时间再做吧,估计思路是相近的。
2781

被折叠的 条评论
为什么被折叠?



