专题【树】刷题日记【树的递归】

题目列表

124. 二叉树中的最大路径和
235. 二叉搜索树的最近公共祖先
543. 二叉树的直径
337. 打家劫舍 III
98. 验证二叉搜索树
104. 二叉树的最大深度
199. 二叉树的右视图
96. 不同的二叉搜索树
100. 相同的树
95. 不同的二叉搜索树 II
226. 翻转二叉树
437. 路径总和 III
257. 二叉树的所有路径
LCR 143. 子结构判断
101. 对称二叉树


124. 二叉树中的最大路径和

题目

二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。

路径和 是路径中各节点值的总和。

给你一个二叉树的根节点 root ,返回其 最大路径和 。

示例 1:
在这里插入图片描述

输入:root = [1,2,3]
输出:6
解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6

示例 2:
在这里插入图片描述

输入:root = [-10,9,20,null,null,15,7]
输出:42
解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42

提示:

  • 树中节点数目范围是 [1, 3 * 104]
  • -1000 <= Node.val <= 1000

思路

分治:

  1. 可能经过根节点
  2. 不经过根节点

答案

/**
 * 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 {
    int result = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        maxRootSum(root);
        return result;
    }
	// 经过根节点的最大路径,注意这里分了两种情况
	// 1. 路径值,因为以这个为根需要和上层节点联通,所以,不能左右子树都取
	// 2. 在计算路径和的时候要都取,因为可能这个跟就是最大路径
    public int maxRootSum(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int r = root.val;
        int left = maxRootSum(root.left);
        int right = maxRootSum(root.right);
        
        r += left > 0 ? left : 0;
        r += right > 0 ? right : 0;
        // 最大根路径,根路径就是路过根但是不包含另一边
        int max = Math.max(0, Math.max(left, right)) + root.val;
        // 这里是计算最大值,可能是经过跟和跟的左右子树
        result = Math.max(result, r);
        return max;
    }
}

235. 二叉搜索树的最近公共祖先

题目

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
在这里插入图片描述
示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。

示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。

说明:

  • 所有节点的值都是唯一的。
  • p、q 为不同节点且均存在于给定的二叉搜索树中。

思路

公共祖先,就是这个节点即是p的父节点或节点本身,又是q的
所以,只要找到p、q让一路返回,找不到的返回null,最后返回的不是空的那个就是答案

答案

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    	// 找到根节点,或者p或者q
        if (root == null || root == p || root == q) {
            return root;
        }
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        // 如果两个都不空,说明,一个在左一个在右,root就是答案
        // 剩下两种情况,说明一个是另一个的父节点
        if (left != null && right != null) {
            return root;
        } else if (left != null) {
            return left;
        } else {
            return right;
        }
    }
}

543. 二叉树的直径

题目

给你一棵二叉树的根节点,返回该树的 直径 。
二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。
两节点之间路径的 长度 由它们之间边数表示。

示例 1:
在这里插入图片描述

输入:root = [1,2,3,4,5]
输出:3
解释:3 ,取路径 [4,2,1,3] 或 [5,2,1,3] 的长度。

示例 2:

输入:root = [1,2]
输出:1

提示:

  • 树中节点数目在范围 [1, 104] 内
  • -100 <= Node.val <= 100

思路

左右字数的高度,加上左右和自己的高度差2
代码设计上和124. 二叉树中的最大路径和一样
一个用来返回,一个用来记录结果(hard和easy设计思路相同)

答案

/**
 * 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 {
    int max = 0;
    public int diameterOfBinaryTree(TreeNode root) {
        high(root);
        return max;
    }

    public int high(TreeNode root) {
        if (root == null) {
            return -1;
        }
        int left = high(root.left);
        int right = high(root.right);
        // 最大高度,可能出现的节点
        max = Math.max(max, left + right + 2);
        // 返回高度值
        return Math.max(left, right) + 1;
    }
}

337. 打家劫舍 III

题目

小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。

除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。

给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。

示例 1:
在这里插入图片描述

输入: root = [3,2,3,null,3,null,1]
输出: 7
解释: 小偷一晚能够盗取的最高金额 3 + 3 + 1 = 7

示例 2:
在这里插入图片描述

输入: root = [3,4,5,1,3,null,1]
输出: 9
解释: 小偷一晚能够盗取的最高金额 4 + 5 = 9

提示:

  • 树的节点数在 [1, 104] 范围内
  • 0 <= Node.val <= 104

思路

拆分成根节点偷和根节点不偷
dp[0]表示根节点不偷,dp[1]表示根节点偷
dp[0] = 左max(偷、不偷) + 右max(偷、不偷)
dp[1] = 左不偷+又不偷+val

答案

/**
 * 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 rob(TreeNode root) {
        int[] result = helper(root);
        return Math.max(result[0], result[1]);
    }

    public int[] helper(TreeNode root) {
        if (root == null) {
            return new int[2];
        }

        int[] result = new int[2];
        int[] left = helper(root.left);
        int[] right =  helper(root.right);
        result[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        result[1] = left[0] + right[0] + root.val;

        return result;
    }
}

98. 验证二叉搜索树

题目

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

节点的左
子树
只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

示例 1:
在这里插入图片描述

输入:root = [2,1,3]
输出:true

示例 2:
在这里插入图片描述

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

提示:

  • 树中节点数目范围在[1, 104] 内
  • -231 <= Node.val <= 231 - 1

思路

左边的最大值 < root.val < 右边的最小值

答案

/**
 * 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 isValidBST(TreeNode root) {
        return is(root, Long.MAX_VALUE, Long.MIN_VALUE);
    }
	
	// 这个树是不是满足,左边的最大值 < root.val < 右边的最小值
    public boolean is(TreeNode root, long max, long min) {
        if (root == null) {
            return true;
        }
        return root.val > min && root.val < max && is(root.left, root.val, min) && is(root.right, max, root.val);
    }
}

104. 二叉树的最大深度

题目

给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

示例 1:
在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:3

示例 2:

输入:root = [1,null,2]
输出:2

提示:

  • 树中节点的数量在 [0, 104] 区间内。
  • -100 <= Node.val <= 100

思路

树的深度,一直遍历到叶子节点返回1(叶子节点需要左右子树都没有)

答案

/**
 * 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 maxDepth(TreeNode root) {
    	// 用root== null,判断可以兼容更多情况
        if (root == null) {
            return 0;
        }

        return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
    }
}

199. 二叉树的右视图

题目

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

示例 1:
在这里插入图片描述

输入: [1,2,3,null,5,null,4]
输出: [1,3,4]

示例 2:

输入: [1,null,3]
输出: [1,3]

示例 3:

输入: []
输出: []

提示:

  • 二叉树的节点个数的范围是 [0,100]
  • -100 <= Node.val <= 100

思路

层序遍历
只输出最后一个节点

答案

/**
 * 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<Integer> rightSideView(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        List<TreeNode> queue = new LinkedList<>();
        if (root != null) {
            queue.add(root);
        }
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.removeFirst();
                // 判断最后一个节点
                if (i == size - 1) {
                    result.add(node.val);
                }
                if (node.left != null) {
                    queue.add(node.left);
                }
                if (node.right != null) {
                    queue.add(node.right);
                }
            }

        }
        return result;
    }
}

96. 不同的二叉搜索树

题目

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。

示例 1:
在这里插入图片描述

输入:n = 3
输出:5

示例 2:

输入:n = 1
输出:1

提示:

  • 1 <= n <= 19

思路

  1. 动态规划
    以第i个节点为root,左右共有dp[i] * dp[n-i-1]
  2. 递归
    同动态规划

答案

// 动态规划
class Solution {
    public int numTrees(int n) {
        int[] dp = new int[n + 1];
        dp[0] = 1;
        dp[1] = 1;
        for (int i = 2; i < dp.length; i++) {
            for (int j = 0; j < i; j++) {
                dp[i] += dp[j] * dp[i - j - 1];
            }
        }
        return dp[n];
    }
}
// 递归
class Solution {
    public int numTrees(int n) {
        return numTrees(1, n);
    }

    public int numTrees(int start, int end) {
        if (start > end) {
            return 1;
        }
        if (start == end) {
            return 1;
        }
       int result = 0;
        for (int i = start; i <= end; i++) {
            result += numTrees(start, i - 1) * numTrees(i + 1, end);
        }
        return result;
    }
}

100. 相同的树

题目

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:
在这里插入图片描述

输入:p = [1,2,3], q = [1,2,3]
输出:true

示例 2:
在这里插入图片描述

输入:p = [1,2], q = [1,null,2]
输出:false

示例 3:
在这里插入图片描述

输入:p = [1,2,1], q = [1,1,2]
输出:false

提示:

  • 两棵树上的节点数目都在范围 [0, 100] 内
  • -104 <= Node.val <= 104

思路

值相同 && 左右也相同

答案

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

95. 不同的二叉搜索树 II

题目

给你一个整数 n ,请你生成并返回所有由 n 个节点组成且节点值从 1 到 n 互不相同的不同 二叉搜索树 。可以按 任意顺序 返回答案。

示例 1:
在这里插入图片描述

输入:n = 3
输出:[[1,null,2,null,3],[1,null,3,2],[2,1,3],[3,1,null,null,2],[3,2,null,1]]

示例 2:

输入:n = 1
输出:[[1]]

提示:

  • 1 <= n <= 8

思路

和上一题的递归思路一样,可以看到n缩小到8了,否则应该会超时

答案

/**
 * 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<TreeNode> generateTrees(int n) {
        return generateTrees(1, n);
    }

    public List<TreeNode> generateTrees(int left, int right) {
        List<TreeNode> result = new ArrayList<>();
        if (left > right) {
            result.add(null);
            return result;
        }


        for (int j = left; j <= right; j++) {
            List<TreeNode> leftNode = generateTrees(left, j - 1);
            List<TreeNode> rightNode = generateTrees(j + 1, right);
            for (TreeNode treeNode : leftNode) {
                for (TreeNode treeNode2 : rightNode) {
                    result.add(new TreeNode(j, treeNode, treeNode2));
                }
            }
        }
        return result;
    }
}

226. 翻转二叉树

题目

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例 1:
在这里插入图片描述

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]

示例 2:
在这里插入图片描述

输入:root = [2,1,3]
输出:[2,3,1]

示例 3:

输入:root = []
输出:[]

提示:

  • 树中节点数目范围在 [0, 100] 内
  • -100 <= Node.val <= 100

思路

递归,先递归左子树再右子树

答案

/**
 * 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 TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return root;
        }

        TreeNode invertTree = invertTree(root.left);
        root.left = invertTree(root.right);
        root.right = invertTree;
        return root;
    }
}

437. 路径总和 III

题目

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。
路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

示例 1:
在这里插入图片描述

输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
解释:和等于 8 的路径有 3 条,如图所示。

示例 2:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:3

提示:

  • 二叉树的节点个数的范围是 [0,1000]
  • -109 <= Node.val <= 109
  • -1000 <= targetSum <= 1000

思路

拆分为过根节点和不过根节点
前缀和

答案

// 递归方式

/**
 * 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 {
    int sum = 0;
    // 过跟 + 不过根的左右子树
    public int pathSum(TreeNode root, int targetSum) {
        if (root == null) {
            return 0;
        }
        int result = 0;

        result += pathSum(root.left, targetSum);
        result += pathSum(root.right, targetSum);
        result += rootSum(root, targetSum);
        return result;
    }
	// 过根节点
    public int rootSum(TreeNode root, long targetSum) {
        int result = 0;
        
        if (root == null) {
            return result;
        }
        if (root.val == targetSum) {
            result++;
        }
        result += rootSum(root.left, targetSum - root.val);
        result += rootSum(root.right, targetSum - root.val);
        return result;
    }
}

// 上面方法有很多重复计算,所以前缀和方式能解
/**
 * 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 pathSum(TreeNode root, int targetSum) {
        Map<Long, Integer> preSum = new HashMap<>();
        preSum.put(0L, 1);
        return dfs(preSum, targetSum, 0, root);
    }

    public int dfs(Map<Long, Integer> preSum, int targetSum, long currentSum, TreeNode root) {
        if (root == null) {
            return 0;
        }

        int result = 0;

        currentSum += root.val;
        result = preSum.getOrDefault(currentSum - targetSum, 0);
        preSum.put(currentSum, preSum.getOrDefault(currentSum, 0) + 1);
        result += dfs(preSum, targetSum, currentSum, root.left);
        result += dfs(preSum, targetSum, currentSum, root.right); 
        preSum.put(currentSum, preSum.getOrDefault(currentSum, 0) - 1);
       
        return result;
    }
}

257. 二叉树的所有路径

题目

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。

示例 1:
在这里插入图片描述

输入:root = [1,2,3,null,5]
输出:[“1->2->5”,“1->3”]

示例 2:

输入:root = [1]
输出:[“1”]

提示:

  • 树中节点的数目在范围 [1, 100] 内
  • -100 <= Node.val <= 100

思路

递归+回溯

答案

/**
 * 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) {
        return binaryTreePaths(root, new ArrayList<>());
    }

    public List<String> binaryTreePaths(TreeNode root, List<Integer> current) {
        List<String> result = new ArrayList<>();
        // 到了最后的节点,开始构建
        if (root.left == null && root.right == null) {
            String r = "";
            for (Integer string : current) {
                r += string + "->";
            }
            result.add(r + root.val);
            return result;
        }
        // 递归常规方法
        current.add(root.val);
        if (root.left != null) {
            result.addAll(binaryTreePaths(root.left, current));
        }
        if (root.right != null) {
            result.addAll(binaryTreePaths(root.right, current));
        }
        current.removeLast();
        return result;
    }

}

LCR 143. 子结构判断

题目

给定两棵二叉树 tree1 和 tree2,判断 tree2 是否以 tree1 的某个节点为根的子树具有 相同的结构和节点值 。
注意,空树 不会是以 tree1 的某个节点为根的子树具有 相同的结构和节点值 。

示例 1:
在这里插入图片描述

输入:tree1 = [1,7,5], tree2 = [6,1]
输出:false
解释:tree2 与 tree1 的一个子树没有相同的结构和节点值。

示例 2:
在这里插入图片描述

输入:tree1 = [3,6,7,1,8], tree2 = [6,1]
输出:true
解释:tree2 与 tree1 的一个子树拥有相同的结构和节点值。即 6 - > 1。

提示:

  • 0 <= 节点个数 <= 10000

思路

  1. 子结构是说是这个树的一部分,即两个数一个包含另一个
  2. 挨个节点找一下,看下是不是以A的节点为重合

答案

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isSubStructure(TreeNode A, TreeNode B) {
    	// 条件说B为null不算,所以返回false,A为null B不可能为A的子集所以也是false
        if (A == null || B == null) {
            return false;
        }
        // 是不是子结构(不包含跟即这个时候B是空的算true)
        if (isSame(A, B)) {
            return true;
        }
        // B虽然不是包括跟的A的子结构,但是可能A的左子树的
        if (isSubStructure(A.left, B)) {
            return true;
        }
        // 右子树同上
        return isSubStructure(A.right, B);
    }
	// 是不是重叠是根的子结构
    public boolean isSame(TreeNode A, TreeNode B) {
    	// B为null,则认为不重复了,所以为true
        if (B == null) {
            return true;
        // A为null,则不可能所以返回false
        } else if (A == null) {
            return false;
        } else {
        	// 是否完全子结构
            return A.val == B.val && isSame(A.left, B.left) && isSame(A.right, B.right);
        }
    }
}

101. 对称二叉树

题目

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:
在这里插入图片描述

输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:
在这里插入图片描述

输入:root = [1,2,2,null,3,null,3]
输出:false

提示:

  • 树中节点数目在范围 [1, 1000] 内
  • -100 <= Node.val <= 100

进阶: 你可以运用递归和迭代两种方法解决这个问题吗?

思路

  1. 递归
  2. 对称

答案



import com.sun.source.doctree.ReturnTree;

/**
 * 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 isSymmetric(TreeNode root) {
        return isSymmetric(root.left, root.right);
    }

    public boolean isSymmetric(TreeNode left, TreeNode right) {
        if (left == null && right == null) {
            return true;
        }
        if (left == null || right == null) {
            return false;
        }
        return left.val == right.val && isSymmetric(left.right, right.left) && isSymmetric(left.left, right.right);
    }
}

  • 25
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值