[路飞]_LeetCode_1305. 两棵二叉搜索树中的所有元素

92 阅读2分钟

「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战

题目

给你 root1 和 root2 这两棵二叉搜索树。

请你返回一个列表,其中包含 两棵树 中的所有整数并按 升序 排序。

示例 1:

image.png

输入:root1 = [2,1,4], root2 = [1,0,3]
输出:[0,1,1,2,3,4]

示例 2:

输入:root1 = [0,-10,10], root2 = [5,1,7,0,2]
输出:[-10,0,0,1,2,5,7,10]

示例 3:

输入:root1 = [], root2 = [5,1,7,0,2]
输出:[0,1,2,5,7]

示例 4:

输入:root1 = [0,-10,10], root2 = []
输出:[-10,0,10]

示例 5:

image.png

输入:root1 = [1,null,8], root2 = [8,1]
输出:[1,1,8,8]

来源:力扣(LeetCode)leetcode-cn.com/problems/al…

解题思路

根据题目提供的信息,是获取二叉树树中的所有元素。二叉搜索树的特性是左子树中每个节点的值小于根节点的值,右子树中每个节点的值大于根节点,通过中序遍历时得到的是一个升序有序数组。中序遍历得到两课树的数组后,因为数组是有序的,所以可以通过线性合并的方式合并为一个数组。

两个数组线性合并方式:

  • 循环遍历两个数组;
  • 比较当前值大小,小的加入结果并且变量自增;
  • 循环结束后其中有一个数组有剩余元素,把剩余元素加入结果;

代码实现

var getAllElements = function (root1, root2) {
    const arr1 = []
    //中序遍历树1得到有序数组
    inorderTraversal(root1, arr1)

    const arr2 = []
    //中序遍历树1得到有序数组
    inorderTraversal(root2, arr2)

    let i = j = 0
    const len1 = arr1.length
    const len2 = arr2.length
    const ans = []

    //将两个数组进行线性合并
    while (i < len1 && j < len2) {
        if (arr1[i] <= arr2[j]) {
            //如果数组1的第i个元素小于数组2的第j个元素
            //把数组1的第i个元素加入结果,并且i自增
            ans.push(arr1[i++])
        } else {
            //把数组2的第j个元素加入结果,并且j自增
            ans.push(arr2[j++])
        }
    }

    //把数组1中剩余的元素加入结果
    while (i < len1) ans.push(arr1[i++])
    //把数组2中剩余的元素加入结果
    while (j < len2) ans.push(arr2[j++])

    return ans
};

//中序遍历
function inorderTraversal(root, arr) {
    if (!root) return
    
    //递归遍历左子树
    inorderTraversal(root.left, arr)
    //记录节点值
    arr.push(root.val)
    //递归遍历右子树
    inorderTraversal(root.right, arr)
}

如有错误欢迎指出,欢迎一起讨论!