LeetCode Day19 二叉树

100 相同的树

题目

给定两棵二叉树的根节点,判断两棵二叉树是否相等。

思路

递归的思路是判断两棵二叉树的左右子树是否相等,当两棵二叉树的对应位置不相同时,返回false,与判断二叉树是否镜像对称类似,只不过从一棵树变成了两棵树。
递归终止的条件,需要分指针为空和不为空的情况,指针为空分为①二叉树1指针为空,树2指针不为空,返回false;②树1不为空,树2为空,返回false;③树1 树2都为空,返回true;则剩下的情况就是两棵树对应节点都不为空,此时如果两树节点所指的值不同,则返回false;接着就只剩下两树节点所指的值相同的情况,这时只要递归判断它们的左右孩子是否相同即可。

代码

/**
 * 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 isSameTree(TreeNode* p, TreeNode* q) {
        if(!p && !q)
            return true;
        else if(!p && q)
            return false;
        else if(p && !q)
            return false;
        else if(p->val != q->val)
            return false;
        return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
    }
};

404 左叶子之和

题目

计算给定二叉树的左叶子之和。
在这里插入图片描述

思路

解决问题的关键是怎样判断是左叶子节点。首先需要有父节点,此节点是父节点的左孩子,然后此节点的左右孩子为空,此时它为左叶子节点。
①用递归的思路,函数参数为根节点,返回左叶子节点和;递归的终止条件为当前根节点为空,返回0;单次递归时,当该节点为左叶子节点时,记录节点值,然后递归求左子树和右子树左叶子之和,相加变为整个树的左叶子之和。
②迭代:可以按照先序遍历的顺序遍历,判断当前节点的左孩子是否为叶子节点,是则累加,不是则继续遍历。

代码

递归:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if(!root)   return 0;
        int sum = 0;
        if(root->left && !root->left->left && !root->left->right)
            sum = root->left->val;
        return sum + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
    }
};

迭代:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if(!root)   return 0;
        stack<TreeNode*> st;
        int sum = 0;
        st.push(root);
        while(!st.empty()) {
            TreeNode* cur = st.top();
            st.pop();
            if(cur->left && !cur->left->left && !cur->left->right)
            {
                sum +=cur->left->val;
            }    
            if(cur->right)
                st.push(cur->right);
            if(cur->left)
                st.push(cur->left);
        }
        return sum;
    }
};

513 找树左下角的值

题目

找到二叉树的最左边的叶子节点的值。
在这里插入图片描述

思路

①层序遍历,只需要返回最后一层的第一个节点值即可。
②用递归的思路,因为要找的是最左边的叶子节点,也就是要找到深度最大的点,按照先序遍历的话,找到的深度最大的点就是最左边的节点值。

代码

层序遍历

/**
 * 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;
        int res;
        if(!root)   
            return 0;
        que.push(root);
        while(!que.empty()) {
            int size = que.size();
            int i = size;
            while(size--) {
                TreeNode* cur = que.front();
                que.pop();
                if(size == i - 1)   res = cur->val;
                if(cur->left)   que.push(cur->left);
                if(cur->right)  que.push(cur->right);
            }
           
        }
        return res;
    }
};

迭代:

/**
 * 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 maxLen = INT_MIN;
    int maxLenValue;
    void getDepth(TreeNode* root,int depth) {
        if(!root)
            return ;
        if(!root->left && !root->right)
        {
            if(depth > maxLen)
            {
                maxLen = depth;
                maxLenValue = root->val;
            }
            return ;
        }
        if(root->left)
            getDepth(root->left,depth + 1);
        if(root->right)
            getDepth(root->right,depth + 1);
        return ;
    }
    int findBottomLeftValue(TreeNode* root) {
        getDepth(root,0);
        return maxLenValue;
    }
};

112 路径总和

题目

给定目标值target,判断树中是否存在根节点到叶子节点的路径和等于目标值。

思路

遍历从根节点到叶子节点的路径,判断路径和是否等于目标值,怎样判断是否等于,可以采用目标值递减的方法。
递归的思路:参数是根节点和目标值,返回bool,递归的终止条件是当根节点为空时,没有值,自然不能等于目标值返回false;每次递归,先判断是否是叶子节点,是的话判断当前目标值和节点值是否相等,相等则返回true,不相等返回false;如果不是叶子节点,则递归判断它的左右子节点是否满足要求。要注意的是目标值需要进行回溯,判断完左节点是否满足要求后,判断右节点时的目标值需要和判断左节点的相同。

代码

/**
 * 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)   return false;
        if(!root->left && !root->right && targetSum == root->val) 
            return true;
        if(!root->left && !root->right)
            return fasle;
        return hasPathSum(root->left,targetSum - root->val) || hasPathSum(root->right,targetSum - root->val);
    }
};

113 路径总和Ⅱ

题目

找到二叉树中所有根节点到叶子节点的路径和等于目标值的路径。

思路

与上一题类似,不过需要做的是保存所有符合条件的路径。用一个二维数组来保存所有满足条件的路径,一个一维数组表示当前路径。

代码

/**
 * 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:
    void findPath(TreeNode* root,int targetSum,vector<int>& path,vector<vector<int>>& res) {
        path.push_back(root->val);
        if(!root->left && !root->right && targetSum == root->val) {
            res.push_back(path);
            return ;
        }
        if(!root->left && !root->right)
            return ;
        if(root->left) {
            findPath(root->left,targetSum - root->val,path,res);
            path.pop_back();
        }
        if(root->right) {
            findPath(root->right,targetSum - root->val,path,res);
            path.pop_back();
        }
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        vector<int> path;
        vector<vector<int>> res;
        if(!root)   return res;
        findPath(root,targetSum,path,res);
        return res;
    }
};

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* build(vector<int>& inorder,int inBegin,int inEnd,vector<int>& postorder,int                       postBegin,int postEnd) {
        if(postEnd == postBegin)
            return nullptr;
        TreeNode* root = new TreeNode(postorder[postEnd - 1]);
        if(postEnd - postBegin == 1)
            return root;
        int i = inBegin;
        for(;i < inEnd;i++) 
            if(inorder[i] == postorder[postEnd - 1])
                break;
        int leftInBegin = inBegin;
        int leftInEnd = i;
        int rightInBegin = i + 1;
        int rightInEnd = inEnd;
        int leftPostBegin = postBegin;
        int leftPostEnd = postBegin + leftInEnd - leftInBegin;
        int rightPostBegin = leftPostEnd;
        int rightPostEnd = postEnd - 1;
        root->left = build(inorder,leftInBegin,leftInEnd,postorder,leftPostBegin,leftPostEnd);
        root->right = build(inorder,rightInBegin,rightInEnd,postorder,rightPostBegin,rightPostEnd);
        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        return build(inorder,0,inorder.size(),postorder,0,postorder.size());
    }
};

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

思路

与上题思路相同。

代码

/**
 * 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>& preorder,int preBegin,int preEnd,vector<int>& inorder,                         int inBegin,int inEnd) {
        if(preBegin == preEnd)  return nullptr;
        TreeNode* root = new TreeNode(preorder[preBegin]);
        if(preEnd - preBegin == 1)  return root;
        int i = inBegin;
        for(;i < inEnd;i++)
            if(inorder[i] == preorder[preBegin])
                break;
        int leftInBegin = inBegin;
        int leftInEnd = i;
        int rightInBegin = i + 1;
        int rightInEnd = inEnd;
        int leftPreBegin = preBegin + 1;
        int leftPreEnd = leftPreBegin + leftInEnd - leftInBegin;
        int rightPreBegin = leftPreEnd;
        int rightPreEnd = preEnd;
        root->left = traversal(preorder,leftPreBegin,leftPreEnd,inorder,leftInBegin,leftInEnd);
        root->right = traversal(preorder,rightPreBegin,rightPreEnd,inorder,rightInBegin,rightInEnd);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return traversal(preorder,0,preorder.size(),inorder,0,inorder.size());
    }
};

654 最大二叉树

思路

只需要递归找到数组最大值,先构造根节点,再分别构造左右子树。

代码

/**
 * 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:
    pair<int,int> max(const vector<int>& nums,int begin,int end){
        pair<int,int> res(INT_MIN,-1);
        for(int i = begin;i < end;i++) {
            if(nums[i] > res.first) {
                res = {nums[i],i};            
            }       
        }
        return res;
    }
    TreeNode* build(vector<int>& nums,int begin,int end) {
        if(begin >= end)
            return nullptr;
        pair<int,int> Max = max(nums,begin,end);
        TreeNode* root = new TreeNode(Max.first);
        int leftBegin = begin;
        int leftend = Max.second;
        int rightBegin = Max.second + 1;
        int rightEnd = end;
        root->left = build(nums,leftBegin,leftend);
        root->right = build(nums,rightBegin,rightEnd);
        return root;
    }
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return build(nums,0,nums.size());
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值