代码随想录算法训练营第十八天|513.找树左下角的值 112. 路径总和 113.路径总和ii 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

题目链接:513.找树左下角的值

递归三部曲:

  1. 确定递归函数的参数和返回值

参数必须有要遍历的树的根节点,还有就是一个int型的变量用来记录最长深度。 这里就不需要返回值了,所以递归函数的返回类型为void。

本题还需要类里的两个全局变量,maxLen用来记录最大深度,result记录最大深度最左节点的数值。

代码如下:

int maxDepth = INT_MIN;
// 全局变量 记录最大深度
int result;
// 全局变量 最大深度最左节点的数值
voidtraversal(TreeNode* root,int depth)
  1. 确定终止条件

当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。

代码如下:

if(root->left ==NULL&& root->right ==NULL)
{       if(depth > maxDepth)
        {
        maxDepth = depth;// 更新最大深度
        result = root->val;// 最大深度最左面的数值
        }
        return;
}
  1. 确定单层递归的逻辑

在找最大深度的时候,递归的过程中依然要使用回溯,代码如下:

    if(root->left)
    {
    depth++;// 深度加一
    traversal(root->left, depth);
    depth--;// 回溯,深度减一
    }
    if(root->right)
    {
    depth++;// 深度加一
    traversal(root->right, depth);
    depth--;// 回溯,深度减一
    }
    return;

完整代码如下:

/**
 * 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;
    void traversal(TreeNode* root,int depth){
        if(root->left==nullptr&&root->right==nullptr)
        {
            if(depth>maxDepth)
            {
                maxDepth=depth;
                result=root->val;
            }
            return;          
        }

        if(root->left)
        {
            depth++;
            traversal(root->left,depth);
            depth--;
        }
        if(root->right)
        {
            depth++;
            traversal(root->right,depth);
            depth--;
        }
        return;
    }
    int findBottomLeftValue(TreeNode* root) {
        traversal(root,0);
        return result;
    }
};

题目链接:112. 路径总和

这道题使用深度优先遍历:

代码如下:

/**
 * 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* root, int count)
    {
        if(!root->left&&!root->right&&count==0)
        {
            return true;
        }
        if(!root->left&&!root->right)
        {
            return false;
        }
        if(root->left)
        {
            count-=root->left->val;
           if(traversal(root->left,count)) return true;
            count+=root->left->val;
        }
        if(root->right)
        {
            count-=root->right->val;
            if(traversal(root->right,count)) return true;
            count+=root->right->val;
        }
        return false;
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==nullptr)
        return false;
        return traversal(root,targetSum-root->val);

    }
};

题目链接:113.路径总和ii

路径总和ii要遍历整个树,找到所有路径,所以递归函数不要返回值!

代码如下:

/**
 * 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 {
private:
    vector<vector<int>> result;
    vector<int> path;
    void traversal(TreeNode* root, int count)
    {
        if(!root->left&&!root->right&&count==0)
        {
            result.push_back(path);
            return;
        }
        if(!root->left&&!root->right)
        {
            return;
        }
        if(root->left)
        {
            path.push_back(root->left->val);
            count-=root->left->val;
            traversal(root->left,count);
            count+=root->left->val;
            path.pop_back();
        }
        if(root->right)
        {
            path.push_back(root->right->val);
            count-=root->right->val;
            traversal(root->right,count);
            count+=root->right->val;
            path.pop_back();
        }
        return;
    }
public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        result.clear();
        path.clear();
        if(root==nullptr) return result;
        path.push_back(root->val);
        traversal(root,targetSum-root->val);
        return result;

    }
};

题目链接:106.从中序与后序遍历序列构造二叉树

说到一层一层切割,就应该想到了递归。

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

代码如下:

/**
 * 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* 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 definitIndex;
        for(definitIndex=0;definitIndex<inorder.size();definitIndex++)
        {
            if(inorder[definitIndex]==rootValue) break;
        }
        //vector<int> leftInorder(inorder.begin(), inorder.begin() + definitIndex);
        vector<int> leftInorder(inorder.begin(),inorder.begin()+definitIndex);
        vector<int> rightInorder(inorder.begin()+definitIndex+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=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 nullptr;
        return traversal(inorder,postorder);
    }
};

题目链接:105.从前序与中序遍历序列构造二叉树

本题和106是一样的道理

代码如下:

/**
 * 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 {
private:
    TreeNode* traversal(vector<int>& preorder, int preBegin,int preEnd,vector<int>& inorder,int inBegin,int inEnd)
    {
        if(preEnd==preBegin) return nullptr;
        int rootValue=preorder[preBegin];
        TreeNode *root=new TreeNode(rootValue);
        if(preEnd-preBegin==1) return root;

        int definitIndex;
        for(definitIndex=inBegin;definitIndex<inEnd;definitIndex++)
        {
            if(inorder[definitIndex]==rootValue) break;
        }
        int leftInorderBegin=inBegin;
        int leftInorderEnd=definitIndex;

        int rightInorderBegin=definitIndex+1;
        int rightInorderEnd=inEnd;

        int leftPreorderBegin=preBegin+1;
        int leftPreorderEnd=preBegin+1+definitIndex-inBegin;

        int rightPreorderBegin=preBegin+1+definitIndex-inBegin;
        int rightPreorderEnd=preEnd;

        root->left=traversal(preorder,leftPreorderBegin,leftPreorderEnd,inorder,leftInorderBegin,leftInorderEnd);
        root->right=traversal(preorder,rightPreorderBegin,rightPreorderEnd,inorder,rightInorderBegin,rightInorderEnd);

        return root;
    }

public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
    {
       if(preorder.size()==0||inorder.size()==0) return nullptr;
       return traversal(preorder,0,preorder.size(),inorder,0,inorder.size());
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值