DAY16 - 513.找树左下角的值,112. 路径总和,106.从中序与后序遍历序列构造二叉树
513.找树左下角的值
层序遍历即可解决。用递归反而不方便。
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> que;
int res=0;
if(root==nullptr) return res;
que.push(root);
while(!que.empty()){
int size=que.size();
res=que.front()->val;
while(size--){
TreeNode* cur=que.front();
if(cur->left!=nullptr) que.push(cur->left);
if(cur->right!=nullptr) que.push(cur->right);
que.pop();
}
}
return res;
}
};
112. 路径总和
暴力解法就是遍历树,计算出到每个叶子结点路径的sum,用set存储,看是否有符合target的。
class Solution {
public:
void getLeafSum(TreeNode* root, unordered_set<int>& sum_set, int sum){
if(root==nullptr) return;
sum+=root->val;
if(root->left==nullptr&&root->right==nullptr){
sum_set.insert(sum);
}
getLeafSum(root->left,sum_set,sum);
getLeafSum(root->right,sum_set,sum);
}
bool hasPathSum(TreeNode* root, int targetSum) {
unordered_set<int> sum_set;
getLeafSum(root,sum_set,0);
if(sum_set.find(targetSum)==sum_set.end()) return false;
else return true;
}
};
但是我看标答采用了回溯法。这样可以减少多余空间的使用并且减少不必要的查找。
class Solution {
private:
bool traversal(TreeNode* cur, int count) {
if (!cur->left && !cur->right && count == 0) return true; // 遇到叶子节点,并且计数为0
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 sum) {
if (root == NULL) return false;
return traversal(root, sum - root->val);
}
};
- 找是否有targetval的一个常用小技巧是不累加sum与targetval比较,而是累减看最终结果是否为0,为0则找到了targetval。
106.从中序与后序遍历序列构造二叉树
学数据结构的时候好像手画过这类题,代码咋写还要思考一下。
class Solution {
public:
TreeNode* traversal(vector<int>& inorder, int ibegin, int iend, vector<int>& postorder, int pbegin, int pend){
if (ibegin > iend || pbegin > pend) return nullptr;
TreeNode* root=new TreeNode(postorder[pend]);
auto it=find(inorder.begin() + ibegin, inorder.begin() + iend + 1,postorder[pend]);
int midindex=distance(inorder.begin(),it);
int leftTreeSize=midindex-ibegin;
root->left=traversal(inorder,ibegin,midindex-1,postorder,pbegin,pbegin+leftTreeSize-1);
root->right=traversal(inorder,midindex+1,iend,postorder,pbegin+leftTreeSize,pend-1);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (inorder.size() == 0 || postorder.size() == 0) return nullptr;
return traversal(inorder,0,inorder.size()-1,postorder,0,postorder.size()-1);
}
};
用index而不是每一回递归都创建新的左右vector比较优雅。
浙公网安备 33010602011771号