代码随想录训练营第十八天打卡| 找树左下角的值 路径总和 从中序与后序遍历序列构造二叉树

找树左下角的值

513.找树左下角的值

1.递归(找到第一个深度最大的叶子结点,返回其值)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public://递归法
int maxDepth=INT_MIN;
int result=0;
void traversal(TreeNode* root,int deep){
    if(root->left==NULL&&root->right==NULL){//递归终止条件
        if(deep>maxDepth){
            maxDepth=deep;
            result=root->val;
        }
        return;
    }
    if(root->left) traversal(root->left,deep+1);//隐藏着回溯
    if(root->right) traversal(root->right,deep+1);
}
    int findBottomLeftValue(TreeNode* root) {
        traversal(root,1);//传入初始参数
        return result;
    }
};

2.迭代,层序遍历(找到最后一层第一个结点,返回其值)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public://层序遍历法
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> que;
        que.push(root);
        vector<int> result;
        while(!que.empty()){
            int size=que.size();
            result.push_back(que.front()->val);//把每一层的第一个结点的值加入数组
            for(int i=0;i<size;i++){
            TreeNode* cur=que.front();
            que.pop();
            if(cur->left) que.push(cur->left);
            if(cur->right) que.push(cur->right);
            }
        }
        return result[result.size()-1];//数组末尾元素就是最后一层第一个元素
    }
};

路径总和

112.路径总和

1.递归(注意递归函数的返回类型,不同的返回类型需要不同的处理方式)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public://递归法
bool traversal(TreeNode* cur,vector<int> &path,int &targetSum){
    path.push_back(cur->val);
    if(cur->left==NULL&&cur->right==NULL){
        int sum=0;
        for(int i=0;i<path.size();i++){//计算路径之和
            sum+=path[i];
        }
        if(sum==targetSum) return true;
    }
    if(cur->left){
        if(traversal(cur->left,path,targetSum)) return true;
        path.pop_back();//回溯
    }
    if(cur->right){
        if(traversal(cur->right,path,targetSum)) return true;
        path.pop_back();//回溯
    }
    return false;
}
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==NULL) return false;
        vector<int> path;
        return traversal(root,path,targetSum);
    }
};

2.递归法精简版(注意回溯的实现)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public://递归法(精简版)
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==nullptr) return false;
        if(!root->left&&!root->right&&root->val==targetSum)
        return true;
        return hasPathSum(root->left,targetSum-root->val)||
        hasPathSum(root->right,targetSum-root->val);
    }
};

3.迭代法,前序遍历版(创建一个栈结构,栈内元素包含当前结点以及当前结点的路径之和,按前序遍历顺序出栈依次判断路径之和是否等于目标值)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public://迭代法(前序遍历版)
    bool hasPathSum(TreeNode* root, int targetSum) {
        if (root == nullptr) return false;
        // 此时栈里要放的是pair<节点指针,路径数值>
        stack<pair<TreeNode*, int>> st;
        st.push(pair<TreeNode*, int>(root, root->val));
        while (!st.empty()) {
            pair<TreeNode*, int> node = st.top();
            st.pop();
            // 如果该节点是叶子节点了,同时该节点的路径数值等于sum,那么就返回true
            if (!node.first->left && !node.first->right && targetSum == node.second)
            return true;

            // 右节点,压进去一个节点的时候,将该节点的路径数值也记录下来
            if (node.first->right) {
                st.push(pair<TreeNode*, int>(node.first->right, 
                node.second + node.first->right->val));
            }

            // 左节点,压进去一个节点的时候,将该节点的路径数值也记录下来
            if (node.first->left) {
                st.push(pair<TreeNode*, int>(node.first->left, 
                node.second + node.first->left->val));
            }
        }
        return false;
    }
};

113.路径总和||

1.递归(注意路径不止一条,要想把递归中获得的路径全部加入,最好设置一个全局变量接收返回路径)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public://递归法
vector<vector<int>> result;//全局变量
vector<int> path;//全局变量
void traversal(TreeNode* cur,int &targetSum){
    path.push_back(cur->val);
    if(cur->left==NULL&&cur->right==NULL){
        int sum=0;
        for(int i=0;i<path.size();i++){//计算路径之和
            sum+=path[i];
        }
        if(sum==targetSum) result.push_back(path);
    }
    if(cur->left){
        traversal(cur->left,targetSum);
        path.pop_back();//回溯
    }
    if(cur->right){
        traversal(cur->right,targetSum);
        path.pop_back();//回溯
    }
    return;
}
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        if(root==NULL) return result;//空节点没有路径
        traversal(root,targetSum);
        return result;
    }
};

2.迭代法(暂时还不会……)

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

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

1.递归法(主要是数组的划分切割)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* buildTree(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 i;
        //找出根节点在中序遍历数组里面的下标进行切割
        for(i=0;i<inorder.size();i++){
            if(inorder[i]==rootValue)
            break;
        }
        //以根节点下标为界切割中序数组(左闭右开根节点不在其中)
        vector<int> leftInorder(inorder.begin(),inorder.begin()+i);
        vector<int> rightInorder(inorder.begin()+i+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;
    }
};

2.迭代法(暂时战略性放弃……)

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

1.递归法(还是划分数组)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        //中序、前序遍历数组相同,判断一个就行
        if(preorder.size()==0) return NULL;
        //不空则前序遍历第一个为根节点,创建一个要返回的根节点接收
        int rootValue=preorder[0];
        TreeNode* root=new TreeNode(rootValue);
        //根节点同时为叶子结点,直接返回
        if(preorder.size()==1) return root;
        int i;
        //找出根节点在中序遍历数组里面的下标进行切割
        for(i=0;i<inorder.size();i++){
            if(inorder[i]==rootValue)
            break;
        }
        //以根节点下标为界切割中序数组(左闭右开根节点不在其中)
        vector<int> leftInorder(inorder.begin(),inorder.begin()+i);
        vector<int> rightInorder(inorder.begin()+i+1,inorder.end());
        //前序遍历第一个结点已经加入故抛弃
        preorder.erase(preorder.begin());
        //把剩余前序遍历数组切割成对应的两部分
        vector<int> leftPreorder(preorder.begin(),preorder.begin()+leftInorder.size());
        vector<int> rightPreorder(preorder.begin()+leftInorder.size(),preorder.end());
        //递归切割好的左右中序前序数组
        root->left=buildTree(leftPreorder,leftInorder);
        root->right=buildTree(rightPreorder,rightInorder);
        //返回根节点
        return root;
    }
};

2.迭代法(战略性放弃……)

今日总结:递归大法好啊。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值