返回

二叉树算法题干详解,从基础到进阶,高效刷题指南(Java)

Android

二叉树算法解析:从基础到进阶

二叉树是一种广泛应用于算法和数据结构领域的非线性数据结构。其结构的特点和丰富的算法应用使得它成为程序员必须掌握的重要知识。本文将深入解析 12 道精心挑选的 LeetCode 二叉树算法题干,涵盖从基础到进阶的各个层面,帮助读者全面提升二叉树算法技能。

基础题:翻转二叉树

题目:给定一棵二叉树,将其翻转。

解答:翻转二叉树的关键是交换每个节点的左右子树。我们可以使用前序遍历的方式,访问每个节点时,将其左右子树指针互换即可。

public TreeNode invertTree(TreeNode root) {
    if (root == null) {
        return null;
    }
    TreeNode left = invertTree(root.left);
    TreeNode right = invertTree(root.right);
    root.left = right;
    root.right = left;
    return root;
}

基础题:对称二叉树

题目:判断一棵二叉树是否为镜像对称。

解答:对称二叉树的判定方法是递归地比较其左右子树是否对称。对于每个节点,如果其左右子树分别是对称的,且当前节点的值也相同,则该二叉树为对称的。

public boolean isSymmetric(TreeNode root) {
    return isMirror(root, root);
}

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

进阶题:路径总和

题目:给定一棵二叉树和一个目标和,判断是否存在从根节点到叶节点的路径,其节点值之和等于目标和。

解答:路径总和问题的解决思路是使用递归沿着每条路径累加节点值,如果累加值等于目标和,则返回 true。

public boolean hasPathSum(TreeNode root, int targetSum) {
    if (root == null) {
        return false;
    }
    if (root.left == null && root.right == null) {
        return root.val == targetSum;
    }
    return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
}

基础题:二叉树的最大深度

题目:计算二叉树的最大深度。

解答:二叉树的最大深度可以递归求解。对于每个节点,其最大深度为其左右子树最大深度中较大的值加 1。

public int maxDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}

进阶题:验证二叉搜索树

题目:验证一棵二叉树是否为二叉搜索树。

解答:验证二叉搜索树的难点在于,其左子树的所有节点值都必须小于当前节点值,而右子树的所有节点值都必须大于当前节点值。我们可以使用递归的方式,对于每个节点,检查其左右子树是否满足二叉搜索树性质。

public boolean isValidBST(TreeNode root) {
    return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
}

public boolean isValidBST(TreeNode root, long min, long max) {
    if (root == null) {
        return true;
    }
    if (root.val <= min || root.val >= max) {
        return false;
    }
    return isValidBST(root.left, min, root.val) && isValidBST(root.right, root.val, max);
}

进阶题:从中序与后序遍历序列构造二叉树

题目:根据一棵二叉树的中序遍历和后序遍历序列,重建二叉树。

解答:从中序与后序遍历序列构造二叉树的思路是,根据后序遍历序列的最后一个元素作为根节点,然后根据中序遍历序列分割左右子树。

public TreeNode buildTree(int[] inorder, int[] postorder) {
    return buildTree(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);
}

public TreeNode buildTree(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd) {
    if (inStart > inEnd || postStart > postEnd) {
        return null;
    }
    int rootVal = postorder[postEnd];
    int rootIndex = inStart;
    while (inorder[rootIndex] != rootVal) {
        rootIndex++;
    }
    TreeNode root = new TreeNode(rootVal);
    int leftSize = rootIndex - inStart;
    root.left = buildTree(inorder, inStart, rootIndex - 1, postorder, postStart, postStart + leftSize - 1);
    root.right = buildTree(inorder, rootIndex + 1, inEnd, postorder, postStart + leftSize, postEnd - 1);
    return root;
}

进阶题:二叉树的层序遍历

题目:以层序遍历的形式打印二叉树。

解答:层序遍历二叉树可以使用队列来实现。我们将根节点加入队列,然后依次将队列中的节点出队,并将其左右子节点加入队列,如此重复,直到队列为空。

public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> result = new ArrayList<>();
    if (root == null) {
        return result;
    }
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        int size = queue.size();
        List<Integer> level = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            TreeNode node = queue.poll();
            level.add(node.val);
            if (node.left != null) {
                queue.offer(node.left);
            }
            if (node.right != null) {
                queue.offer(node.right);
            }
        }
        result.add(level);
    }
    return result;
}

进阶题:二叉树的锯齿形层序遍历

题目:以锯齿形层序遍历的形式打印二叉树,即奇数层从左到右,偶数层从右到左。

解答:锯齿形层序遍历二叉树可以使用两个栈来实现。我们将根节点加入第一个栈,然后依次将第一个栈中的节点出栈,并将其左右子节点加入第二个栈。然后交换第一个栈和第二个栈,重复上述步骤,直到两个栈都为空。

public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
    List<List<Integer>> result = new ArrayList<>();
    if (root == null) {
        return result;
    }
    Stack<TreeNode> stack1 = new Stack<>();
    Stack<TreeNode> stack2 = new Stack<>();
    stack1.push(root);
    while (!stack1.isEmpty() || !stack2.isEmpty()) {
        List<Integer> level = new ArrayList<>();
        if (!stack1.isEmpty()) {
            while (!stack1.isEmpty()) {
                TreeNode node = stack1.pop();
                level.add(node.val);
                if (node.left != null) {
                    stack2.push(node.left);
                }
                if (node.right != null) {
                    stack2.push(node.right);
                }
            }
        } else {
            while (!stack2.isEmpty()) {
                TreeNode node = stack2.pop();
                level.add(node.val);
                if (node.right != null) {
                    stack1.push(node.right);
                }
                if (node.left != null) {
                    stack1.push(node.left);
                }
            }
        }
        result.add(level);
    }
    return result;
}

结语

通过对这 12 道二叉树算法题干的解析,我们深入了解了二叉树的基本操作、遍历算法、以及一些进阶的构造和验证算法。这些算法在计算机科学和软件开发中都有着广泛的应用。掌握这些算法,