leetcode刷穿二叉树

Posted 深林无鹿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode刷穿二叉树相关的知识,希望对你有一定的参考价值。

二叉树我又双叒叕来啦~

在这里插入图片描述

这里有leetcode题集分类整理!!!

  • leetcode 654. 最大二叉树
  • leetcode 617. 合并二叉树
  • leetcode 700. 二叉搜索树中的搜索
  • leetcode 98. 验证二叉搜索树
  • leetcode 530. 二叉搜索树的最小绝对差
    1、最大二叉树
    题目难度:中等
    题目描述:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    解题思路:

看到这种构造二叉树类型的八成就是递归了,然后分为左孩子群和右孩子群,在通过获得左孩子群的最大节点又分为左孩子群的左孩子群和左孩子群的右孩子群… …
特别注意参数传递的设计和边界条件的判断

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
       // 这里有边界采用nums.length 而不是 nums.length - 1
       return construct(nums, 0, nums.length);
    }

    public TreeNode construct(int[] nums, int l, int r) {
        // 边界条件
        if (l == r) return null;
        int maxIndex = getMaxIndex(nums, l, r);
        TreeNode node = new TreeNode(nums[maxIndex]);
        // 这里的参数传递尤为细节,切不可误写成maxIndex - 1
        node.left = construct(nums, l, maxIndex);
        node.right = construct(nums, maxIndex + 1, r);
        return node;
    }

    public int getMaxIndex(int[] nums, int l, int r) {
        int maxIndex = l;
        // 根据有边界无法相等注意细节处理
        for (int i = l; i < r; i ++) {
            if (nums[maxIndex] < nums[i]) {
                maxIndex = i;
            }
        }
        return maxIndex;
    }
}

2、合并二叉树
题目难度:简单
题目描述:
在这里插入图片描述
解题思路:

又是构造二叉树,依然是递归思路
确定边界条件:
合并空节点,返回不是空节点的那个,都为空,就为空。
递归过程:当前合并节点值为两个树节点的值之和
左节点和左节点合并,右节点和右节点合并

class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1 == null) return root2;
        if (root2 == null) return root1;
        TreeNode node = new TreeNode(root1.val + root2.val);
        node.left = mergeTrees(root1.left, root2.left);
        node.right = mergeTrees(root1.right, root2.right);
        return node;
    }
}

3、二叉搜索树中的搜索
题目难度:简单
题目描述:
在这里插入图片描述
解题思路:

BST搜索对递归为经典。
这里不做过多阐释,后面在美化一下代码。

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null) return root;
        if (root.val == val) return root;
        else if (val < root.val) return searchBST(root.left, val);
        else if (val > root.val) return searchBST(root.right, val);
        return root;
    }
}

代码美化:

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if(root == null || root.val == val) return root;
        return val > root.val ? searchBST(root.right, val) : searchBST(root.left, val);
    }
}

4、验证二叉搜索树
题目难度:中等
题目描述:
在这里插入图片描述
解题思路一(经典递归):

判断二叉树是否为BST,在递归传参的时候一定要传入正确的判断条件
即上界和下界,来判断子树是否满足条件

class Solution {
    public boolean isValidBST(TreeNode root) {
        if (root == null) return true;
        return check(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }
	// 传递参数 lower 下界、upper 上界
    public boolean check(TreeNode node, long lower, long upper) {
        if (node == null) return true;
        if (node.val <= lower || node.val >= upper) return false;
        return check(node.left, lower, node.val) && check(node.right, node.val, upper);
    }
}

解题思路二(BST特性:中序遍历):

class Solution {
    public boolean isValidBST(TreeNode root) {
        Deque<TreeNode> stack = new LinkedList<TreeNode>();
        double inorder = -Double.MAX_VALUE;

        while (!stack.isEmpty() || root != null) {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
              // 如果中序遍历得到的节点的值小于等于前一个 inorder,说明不是二叉搜索树
            if (root.val <= inorder) {
                return false;
            }
            inorder = root.val;
            root = root.right;
        }
        return true;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/validate-binary-search-tree/solution/yan-zheng-er-cha-sou-suo-shu-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

5、二叉搜索树的最小绝对差
题目难度:简单
题目描述:
在这里插入图片描述
解题思路:

第一反应是利用二叉搜索树中序遍历的有序性解决:
将结果加入ArrayList中在遍历获得每俩个相邻元素差值的最小值

class Solution {
    public int getMinimumDifference(TreeNode root) {
        List<Integer> valueList = new ArrayList<>();
        inOrderTraversal(root, valueList);
        int ans = Integer.MAX_VALUE;
        for (int i = 1; i < valueList.size(); i ++) {
            ans = Math.min(ans, Math.abs(valueList.get(i) - valueList.get(i - 1)));
        }
        return ans;
    }

    public void inOrderTraversal(TreeNode root, List<Integer> valueList) {
        if (root == null) return;
        inOrderTraversal(root.left, valueList);
        valueList.add(root.val);
        inOrderTraversal(root.right, valueList);
    }
}

写完突然发现每次记录的时候只需要记录当前节点值与上一个值的差值就可以求得结果,于是可以直接把ArrayList优化掉:

class Solution {
    private int ans = Integer.MAX_VALUE;
    private int prev = -1;
    public int getMinimumDifference(TreeNode root) {
        inOrderTraversal(root);
        return ans;
    }

    public void inOrderTraversal(TreeNode root) {
        if (root == null) return;
        inOrderTraversal(root.left);
        if (prev == -1) prev = root.val;
        else {
            ans = Math.min(ans, root.val - prev);
            prev = root.val;
        }
        inOrderTraversal(root.right);
    }
}

以上是关于leetcode刷穿二叉树的主要内容,如果未能解决你的问题,请参考以下文章

leetcode刷穿二叉树

leetcode刷穿二叉树

leetcode刷穿二叉树

leetcode刷穿二叉树(完结)

leetcode刷穿二叉树(完结)

leetcode刷穿二叉树(完结)