力扣爆刷第141天之二叉树十连刷(翻转、对称、深度、平衡、路径)

力扣爆刷第141天之二叉树十连刷(翻转、对称、深度、平衡、路径)

文章目录

      • 力扣爆刷第141天之二叉树十连刷(翻转、对称、深度、平衡、路径)
      • [一、226. 翻转二叉树](#一、226. 翻转二叉树)
      • [二、101. 对称二叉树](#二、101. 对称二叉树)
      • [三、104. 二叉树的最大深度](#三、104. 二叉树的最大深度)
      • [四、111. 二叉树的最小深度](#四、111. 二叉树的最小深度)
      • [五、222. 完全二叉树的节点个数](#五、222. 完全二叉树的节点个数)
      • [六、110. 平衡二叉树](#六、110. 平衡二叉树)
      • [七、257. 二叉树的所有路径](#七、257. 二叉树的所有路径)
      • [八、404. 左叶子之和](#八、404. 左叶子之和)
      • [九、513. 找树左下角的值](#九、513. 找树左下角的值)
      • [十、112. 路径总和](#十、112. 路径总和)

一、226. 翻转二叉树

题目链接:https://leetcode.cn/problems/invert-binary-tree/description/

思路:直接前序遍历,然后在遍历的过程中交换左右子节点。

java 复制代码
class Solution {
    public TreeNode invertTree(TreeNode root) {
        traverse(root);
        return root;
    }
    void traverse(TreeNode root) {
        if(root == null) return ;
        TreeNode t = root.left;
        root.left = root.right;
        root.right = t;
        traverse(root.left);
        traverse(root.right);
    }

}

二、101. 对称二叉树

题目链接:https://leetcode.cn/problems/symmetric-tree/description/

思路:将一个棵二叉树当做两颗二叉树来遍历,也就是在递归的函数参数中携带左右两颗子树,然后进行比较。

java 复制代码
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return traverse(root.left, root.right);
    }

    boolean traverse(TreeNode node1, TreeNode node2) {
        if(node1 == null && node2 == null) return true;
        if(node1 == null || node2 == null) return false;
        if(node1.val != node2.val) return false;
        return traverse(node1.left, node2.right) && traverse(node1.right, node2.left);
    }
    
}

三、104. 二叉树的最大深度

题目链接:https://leetcode.cn/problems/maximum-depth-of-binary-tree/description/

思路:后序遍历,返回左右子树的最大值即可,然后每返回一层就加1,即可得到最大深度。

java 复制代码
class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null) return 0;
        int left = maxDepth(root.left);
        int right = maxDepth(root.right);
        return Math.max(left, right) + 1;
    }
}

四、111. 二叉树的最小深度

题目链接:https://leetcode.cn/problems/minimum-depth-of-binary-tree/description/

思路:求最小深度,需要从上往下找,使用前序遍历,递归终点为叶子节点,到达叶子节点进行判断。

java 复制代码
class Solution {
    int min = Integer.MAX_VALUE;
    public int minDepth(TreeNode root) {
        if(root == null) return 0;
        traverse(root, 1);
        return min;
    }

    void traverse(TreeNode root, int deep) {
        if(root == null) return;
        if(root.left == null && root.right == null) {
            min = Math.min(min, deep);
            return ;
        }
        traverse(root.left, deep+1);
        traverse(root.right, deep+1);
    }
}

五、222. 完全二叉树的节点个数

题目链接:https://leetcode.cn/problems/count-complete-tree-nodes/description/

思路:求完全二叉树的节点个数,思路很简单,就是利用完全二叉树的性质,可以根据深度计算个数,所以就前序遍历,每一个节点都判断是否是完全二叉树,是就不遍历了,不是再遍历。

java 复制代码
class Solution {
    public int countNodes(TreeNode root) {
        if(root == null) return 0;
        int a = 0, b = 0;
        TreeNode p = root, q = root;
        while(p != null) {
            a++;
            p = p.left;
        }
        while(q != null) {
            b++;
            q = q.right;
        }
        if(a == b) return (int)Math.pow(2, a) - 1;
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}

六、110. 平衡二叉树

题目链接:https://leetcode.cn/problems/balanced-binary-tree/description/

思路:平衡二叉树是指左右子高度相差不超过1,所以直接按照求树的深度就可以解题,只要左右深度大于1,即不平衡。

java 复制代码
class Solution {
    boolean flag = true;
    public boolean isBalanced(TreeNode root) {
        traverse(root);
        return flag;
    }

    int traverse(TreeNode root) {
        if(root == null) return 0;
        int left = traverse(root.left);
        int right = traverse(root.right);
        if(Math.abs(left - right) > 1) {
            flag = false;
        }
        return Math.max(left, right) + 1;
    }
}

七、257. 二叉树的所有路径

题目链接:https://leetcode.cn/problems/binary-tree-paths/description/

思路:求所有路径,这种题目在回溯中非常常见,所以本题也是在递归的过程中使用回溯,在叶子节点进行路径组装。

java 复制代码
class Solution {
    List<String> result = new ArrayList<>();
    List<Integer> list = new ArrayList<>();
    public List<String> binaryTreePaths(TreeNode root) {
        traverse(root);
        return result;
    }
    void traverse(TreeNode root) {
        list.add(root.val);
        if(root.left == null && root.right == null) {
            StringBuilder sb = new StringBuilder();
            for(int i : list) {
                sb.append(i).append("->");
            }
            sb.delete(sb.length()-2, sb.length());
            result.add(sb.toString());
            return;
        }
        
        if(root.left != null) {
            traverse(root.left);
            list.remove(list.size()-1);
        }
        if(root.right != null) {
            traverse(root.right);
            list.remove(list.size()-1);
        }
    }
}

八、404. 左叶子之和

题目链接:https://leetcode.cn/problems/sum-of-left-leaves/description/

思路:求左叶子之和,求的是所有的左叶子的和,所以只需要做两件事情,一件是在叶子节点进行判断,另外一件是提供每个节点的信息,用于判断当前节点是否是叶子节点,这种信息需要从父节点传递,所以在递归函数的参数中。

java 复制代码
class Solution {
    int sum = 0;
    public int sumOfLeftLeaves(TreeNode root) {
        traverse(root, false);
        return sum;
    }

    void traverse(TreeNode root, boolean flag) {
        if(root == null) return ;
        if(root.left == null && root.right == null && flag) {
            sum += root.val;
        }
        traverse(root.left, true);
        traverse(root.right, false);
    }
}

九、513. 找树左下角的值

题目链接:https://leetcode.cn/problems/find-bottom-left-tree-value/description/

思路:本题和上一题略有差异,上一题是求所有左叶子节点的和,要求的是左叶子节点,本题类似于树的左视图,但是是深度最深的哪一行的最左边的那个节点,它可能是左节点也可能是右节点。只需要前序遍历,利用深度,当深度第一次大于记录值时,说明是第一次到达下一层,而且采用的是前序遍历,到达的是下一层的最左边的叶子节点。

java 复制代码
class Solution {
    int result = 0, max = 0;
    public int findBottomLeftValue(TreeNode root) {
        traverse(root, 1);
        return result;
    }
    void traverse(TreeNode root, int deep) {
        if(root == null) return ;
        if(root.left == null && root.right == null && deep > max) {
            max = deep;
            result = root.val;
        } 
        traverse(root.left, deep + 1);
        traverse(root.right, deep + 1);
    }
}

十、112. 路径总和

题目链接:https://leetcode.cn/problems/path-sum/description/

思路:求路径总和,类似于回溯的用法,就是在树的递归过程中使用回溯,如果是全局变量,需要手动回滚数据,如果是携带是函数参数列表则不需要。

java 复制代码
class Solution {
    boolean flag = false;
    public boolean hasPathSum(TreeNode root, int targetSum) {
        traverse(root, targetSum, 0);
        return flag;
    }
    void traverse(TreeNode root, int targetSum, int sum) {
        if(root == null || flag) return;
        sum += root.val;
        if(root.left == null && root.right == null) {
            if(sum == targetSum) flag = true;
        }
        traverse(root.left, targetSum, sum);
        traverse(root.right, targetSum, sum);
    }
}
相关推荐
JingHongB2 分钟前
代码随想录算法训练营Day55 | 图论理论基础、深度优先搜索理论基础、卡玛网 98.所有可达路径、797. 所有可能的路径、广度优先搜索理论基础
算法·深度优先·图论
weixin_432702265 分钟前
代码随想录算法训练营第五十五天|图论理论基础
数据结构·python·算法·深度优先·图论
小冉在学习8 分钟前
day52 图论章节刷题Part04(110.字符串接龙、105.有向图的完全可达性、106.岛屿的周长 )
算法·深度优先·图论
Repeat7158 分钟前
图论基础--孤岛系列
算法·深度优先·广度优先·图论基础
小冉在学习11 分钟前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论
武子康23 分钟前
大数据-212 数据挖掘 机器学习理论 - 无监督学习算法 KMeans 基本原理 簇内误差平方和
大数据·人工智能·学习·算法·机器学习·数据挖掘
passer__jw7671 小时前
【LeetCode】【算法】283. 移动零
数据结构·算法·leetcode
Ocean☾1 小时前
前端基础-html-注册界面
前端·算法·html
顶呱呱程序1 小时前
2-143 基于matlab-GUI的脉冲响应不变法实现音频滤波功能
算法·matlab·音视频·matlab-gui·音频滤波·脉冲响应不变法
爱吃生蚝的于勒1 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法