代码随想录训练营Day17|树:110.平衡二叉树、257.二叉树的所有路径、404.左叶子之和

LeetCode110:平衡二叉树

思路:递归。和上一题完全二叉树很像,递归判断左右子树是否为平衡二叉树。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isBalanced(TreeNode root) {
        int ans = getBalanced(root);
        return ans !=-1;
    }
    public int getBalanced(TreeNode root){  // 1.明确递归函数的参数和返回值
        if(root == null){   // 2.明确终止条件
            return 0;   
        }
        // 3.明确单层递归逻辑
        int left = getBalanced(root.left); // 得到左子树的高度
        if(left == -1){     // 如果左子树已经不是平衡了 直接返回-1
            return -1;
        }
        int right = getBalanced(root.right);// 得到右子树的高度
        if(right == -1){    // 如果右子树不平衡了,直接返回-1
            return -1;
        }

        return Math.abs(left-right)>1? -1: Math.max(left, right)+1; // 中 如果发现当前节点的左子树和右子树的高度差大于1 则返回-1。标记这一节点下面的子树已经不平衡了。
        // 否则就是返回当前父节点的高度(记得+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 isBalanced(TreeNode* root) {

        if(getBalanced(root) != -1){
            return true;
        }
        else{
            return false;
        }
    }

    int getBalanced(TreeNode* node){
        if(node == NULL) return 0;
        int left = getBalanced(node->left);
        if(left == -1) return -1; .// 注意这里要先一步判断,如果左子树已经存在-1的情况要将-1传上去的 不要忘了。
        int right = getBalanced(node->right);
        if(right == -1) return -1;
        if(abs(left - right) > 1){
            return -1;
        }
        else{
            return 1 + max(left, right);
        }
    }
};

LeetCode257:二叉树的所有路径

思路:这种找到所有子集合的问题,都用可以考虑回溯来做。与递归的区别是在递归处理之后多了一步回退的操作。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        // 回溯
        // 做回溯练习题的的时候可以debug来验证流程
        // 在一旁画一个栈。模拟整个过程
        List<String> ans = new ArrayList<>(); // 用来存放最后的结果String
        if(root == null){
            return ans;
        }
        List<Integer> path = new ArrayList<>(); // 用来存放回溯之前找到的结果,也就是每个路径。
        traversal(root, path, ans);
        return ans;
    }
    public void traversal(TreeNode node, List<Integer> path, List<String> ans){
        path.add(node.val); // 要在一开始就加上,不然后下面的for判断的时候是依据这个节点的叶子节点,进去了之后就直接返回最后结果就会丢弃这个node了。
        if(node.left == null && node.right == null){ // 到了叶子节点
        StringBuilder sb = new StringBuilder();
            for(int i=0;i<path.size()-1;i++){ // 因为拼接 最后一个单独处理
                sb.append(path.get(i)).append("->");
            }
            sb.append(path.get(path.size() - 1));
            ans.add(sb.toString()); // 将这一段从根节点到叶子节点的所有节点收录
        }
        if(node.left != null){ // 左侧没有到叶子节点,继续往下找
            traversal(node.left, path, ans); // 运行到最后肯定会找到路径的
            path.remove(path.size() - 1);   // 将当前找到的最后一个删掉,依次类推,从后往前删。去找右侧的路劲
        }
        if(node.right != null){
            traversal(node.right, path, ans);
            path.remove(path.size() - 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 {

private:
    void traversal(TreeNode* node, vector<int> & path, vector<string>& ans){
        path.push_back(node->val);  // 这个path 只又来暂存路劲的数值元素,后面再加上-> 并且变成字符串
        if(node->left == NULL && node->right == NULL){
            // 如果当前node的左右子节点为NULL 表示到达了需要处理的路径要添加到ans里面去了
            string strPath;
            int size = path.size() - 1; // 这是因为最后一个数值放在外面处理,在这里处理的话还要加一步判断吧,最后一个-> 删除掉;也可以理解为只要加size个->
            for(int i=0;i<size;i++){
                strPath += to_string(path[i]); // 注意要to_string转换成String类型
                strPath += "->";
            }
            strPath += to_string(path[size]); // 加上最后一个节点值
            ans.push_back(strPath);

        }

        if(node->left){
            traversal(node->left, path, ans);
            path.pop_back();
        }
        if(node->right){
            traversal(node->right, path, ans);
            path.pop_back();
        }
    }
public:
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<int> path;
        vector<string> ans;
        if(root == NULL) return ans;
        traversal(root, path, ans);
        return ans;
    }
};

LeetCode404:左叶子结点之和

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        // 后序遍历一层一层的向上返回左右子树的左叶子结果
        if(root == null){
            return 0;
        }
        int left = sumOfLeftLeaves(root.left); // 左:得到左子树的左叶子结点
        int right = sumOfLeftLeaves(root.right);// 右:得到右子树的左叶子结点
        int temp = 0;
        if(root.left != null && root.left.left == null && root.left.right == null){
            temp = root.left.val;
        }
        return temp + left + right; // 中:左右求和
    }
}
/**
 * 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:
    int getLeftSum(TreeNode* node){
        if(node == NULL){
            return 0;
        }
        int left = getLeftSum(node->left);
        // 要处理哪一部分 就在哪一部分后面加一个逻辑处理的部分
        // 通过通过停止的逻辑 是无法知道当前是不是左子节点的,
        // 只有通过父节点再来放下找,再能判断是不是左子节点
        if(node->left != NULL && node->left->left == NULL && node->left->right == NULL){ 
            left = node->left->val;
        }
        int right = getLeftSum(node->right);
        return left+right;
        
    }
public:
    int sumOfLeftLeaves(TreeNode* root) {
        int ans = 0;
        if(root == NULL) return ans;
        ans = getLeftSum(root);
        return ans;
    }
};

迭代法

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        // 用栈来实现一遍
        Stack<TreeNode> stack = new Stack<>();
        if(root == null){
            return 0;
        }
        stack.push(root);
        int ans = 0;
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            if(node.left != null && node.left.left ==null&& node.left.right == null){// 只能在叶子节点的上一位来判断,不然进入到叶子节点之后无法判断是左叶子还有右叶子
                ans += node.left.val;
            }
            if(node.left != null){ // 这里先push left还是right 不影响。因为他们做叶子节点的相对位置是不变的。
                stack.push(node.left);
            }
            if(node.right != null){
                stack.push(node.right);
            }
            
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值