513.找树左下角的值

本题用前中后序都可以(都是先遍历左再遍历右,保证最后一定是左侧的节点),因为没有中节点的处理逻辑,用全局变量记录最大深度,只要遇到叶子结点并且当前深度比最大深度大,就更新,同时用到了回溯。

深度最大的叶子结点是最后一行。左侧的节点不一定是左孩子。

class Solution {
public:
    int maxDepth=0;
    int res;
    void traversal(TreeNode* node,int depth){
        if(node->left==NULL&&!node->right&&depth>maxDepth){
            maxDepth=depth;
            res=node->val;
        }
        if(node->left){
            depth++;
            traversal(node->left,depth);
            depth--;
        }
        if(node->right){
            depth++;
            traversal(node->right,depth);
            depth--;
        }
    }
    int findBottomLeftValue(TreeNode* root) {
        traversal(root,1);
        return res;
    }
};

迭代法:(层序遍历)

用每一层的第一个元素更新结果值res,最后返回的就是最后一层第一个元素。每次循环,队列都要一边弹出元素一边加入元素。

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> que;
        if(root) que.push(root);
        int res;
        while(!que.empty()){
            //先记录当前层的元素个数
            int size=que.size();
            for(int i=0;i<size;i++){
                TreeNode* node=que.front();
                que.pop();
                if(i==0) res=node->val;
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        return res;
    }
};

112. 路径总和 

也是前中后序都可以,不存在中节点的处理逻辑。代码中有两处返回false的逻辑,第一处是单条路径不符合的话,返回false,第二处是如果所有的路径尝试后都没有返回true的话,就返回false。注意传入下层递归函数的值是已经减去节点后的值。

class Solution {
public:
    bool traversal(TreeNode* node,int curSum){
        if(!node->left&&!node->right&&curSum==0) return true;
        else if(!node->left&&!node->right&&curSum!=0) return false;
        //以上两个返回信息仅用于递归时
        if(node->left){
            curSum-=node->left->val;
            if(traversal(node->left,curSum)) return true;//下面的孩子节点告诉当前节点存在路径,那就继续向上返回true的信息
            curSum+=node->left->val;
        }
        if(node->right){
            curSum-=node->right->val;
            if(traversal(node->right,curSum)) return true;
            curSum+=node->right->val;
        }
        return false;
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(!root) return false;
        return traversal(root,targetSum-root->val);
    }
};

113.路径总和ii

注意终止条件有两个,符合/不符合,然后注意在进行下一层递归之前path已经记录了节点的数值,传入递归函数的数也是减去后的数。

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;
    void traversal(TreeNode* node,int cursum){
        //终止条件有两个,一个是符合条件,一个是不符合条件
        if(!node->left&&!node->right&&cursum==0){
            res.push_back(path);
            return;
        }
        if(!node->left&&!node->right) return;
        if(node->left){
            path.push_back(node->left->val);
            cursum-=node->left->val;
            traversal(node->left,cursum);
            cursum+=node->left->val;
            path.pop_back();
        }
        if(node->right){
            path.push_back(node->right->val);
            cursum-=node->right->val;
            traversal(node->right,cursum);
            cursum+=node->right->val;
            path.pop_back();
        }
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        res.clear();
        path.clear();
        if(!root) return res;
        path.push_back(root->val);
        traversal(root,targetSum-root->val);
        return res;
    }
};

106.从中序与后序遍历序列构造二叉树 

1、如果后序数组的元素个数为0,则返回NULL

2、如果不为空,取后序数组最后一个元素为根节点的值

3、找到后序数组最后一个元素在中序数组中的位置

4、切中序数组

5、切后序数组

6、递归构造二叉树

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(postorder.size()==0) return NULL;
        //如果不为空,取后序数组最后一个元素为节点元素
        int rootval=postorder[postorder.size()-1];
        TreeNode* root=new TreeNode(rootval);
        if(postorder.size()==1) return root;
        //找后序数组最后一个元素在中序数组中的位置,作为切割点
        int idx;
        for(idx=0;idx<inorder.size();idx++){
            if(inorder[idx]==rootval) break;
        }
        //切中序数组
        vector<int> leftinorder(inorder.begin(),inorder.begin()+idx);
        vector<int> rightinorder(inorder.begin()+idx+1,inorder.end());
        //切后序数组
        postorder.resize(postorder.size()-1);
        vector<int> leftpostorder(postorder.begin(),postorder.begin()+leftinorder.size());
        vector<int> rightpostorder(postorder.begin()+leftinorder.size(),postorder.end());
        root->left=buildTree(leftinorder,leftpostorder);
        root->right=buildTree(rightinorder,rightpostorder);
        return root;
    }
};

105.从前序与中序遍历序列构造二叉树

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.size()==0) return NULL;
        int rootval=preorder[0];
        TreeNode* root=new TreeNode(rootval);
        if(preorder.size()==1) return root;
        int index;
        for(index=0;index<inorder.size();index++){
            if(inorder[index]==preorder[0]) break;
        }
        vector<int> leftinorder(inorder.begin(),inorder.begin()+index);
        vector<int> rightinorder(inorder.begin()+index+1,inorder.end());
        
        vector<int> leftpreorder(preorder.begin()+1,preorder.begin()+leftinorder.size()+1);
        vector<int> rightpreorder(preorder.begin()+leftinorder.size()+1,preorder.end());
        root->left=buildTree(leftpreorder,leftinorder);
        root->right=buildTree(rightpreorder,rightinorder);
        return root;
    }
};

划分左中序区间的时候边界问题出错。

06-10 22:21