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

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

示例 1:

输入: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:

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

提示:

每棵树最多有 5000 个节点。

每个节点的值在 [-10^5, 10^5] 之间。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/all-elements-in-two-binary-search-trees

方法一:遍历 + 排序

我们可以想到的最简单的方法是,对两棵树进行任意形式的遍历(深度优先搜索、广度优先搜索、前序遍历、中序遍历、后序遍历),并将遍历到的所有元素放入一个数组中,最后对这个数组进行排序即可。

C++

class Solution {
public:
void dfs(TreeNode* node, vector<int>& ans) {
if (!node) {
return;
}
ans.push_back(node->val);
dfs(node->left, ans);
dfs(node->right, ans);
} vector<int> getAllElements(TreeNode* root1, TreeNode* root2) {
vector<int> ans;
dfs(root1, ans);
dfs(root2, ans);
sort(ans.begin(), ans.end());
return ans;
}
};

Python

class Solution:
def getAllElements(self, root1: TreeNode, root2: TreeNode) -> List[int]:
ans = list() def dfs(node):
if not node:
return
ans.append(node.val)
dfs(node.left)
dfs(node.right) dfs(root1)
dfs(root2)
ans.sort()
return ans

复杂度分析

时间复杂度:O((M+N)log(M+N)),其中 M 和 N 是两棵树中的节点个数。

空间复杂度:O(H_M + H_N + log(M + N)),其中 H_M 和 H_N是两棵树的高度,这里只计算除了存储答案的数组以外需要的额外空间。上面给出的代码使用深度优先搜索对两棵树进行遍历,需要 O(H_M + H_N)的栈空间;在对数组进行排序时,需要log(M+N) 的栈空间。

方法二:中序遍历 + 归并排序

方法一中并没有用到二叉搜索树本身的性质。如果我们对二叉搜索树进行中序遍历,就可以直接得到树中所有元素升序排序后的结果。因此我们可以对两棵树分别进行中序遍历,得到数组 v1 和 v2,它们分别存放了两棵树中的所有元素,且均已有序。在这之后,我们通过归并排序的方法对 v1 和 v2 进行排序,就可以得到最终的结果。

C++

class Solution {
public:
void dfs(TreeNode* node, vector<int>& v) {
if (!node) {
return;
}
dfs(node->left, v);
v.push_back(node->val);
dfs(node->right, v);
} vector<int> getAllElements(TreeNode* root1, TreeNode* root2) {
vector<int> v1, v2;
dfs(root1, v1);
dfs(root2, v2); vector<int> ans;
int i = 0, j = 0;
while (i < v1.size() || j < v2.size()) {
if (i < v1.size() && (j == v2.size() || v1[i] <= v2[j])) {
ans.push_back(v1[i++]);
}
else {
ans.push_back(v2[j++]);
}
}
return ans;
}
};

Python

class Solution:
def getAllElements(self, root1: TreeNode, root2: TreeNode) -> List[int]:
def dfs(node, v):
if not node:
return
dfs(node.left, v)
v.append(node.val)
dfs(node.right, v) v1, v2 = list(), list()
dfs(root1, v1)
dfs(root2, v2)
ans, i, j = list(), 0, 0
while i < len(v1) or j < len(v2):
if i < len(v1) and (j == len(v2) or v1[i] <= v2[j]):
ans.append(v1[i])
i += 1
else:
ans.append(v2[j])
j += 1
return ans

复杂度分析

时间复杂度:O(M+N),其中 M 和 N 是两棵树中的节点个数。中序遍历的时间复杂度为 O(M+N),归并排序的时间复杂度同样为 O(M+N)。

空间复杂度:O(M+N)。我们需要使用额外的空间存储数组 v1 和 v2。

方法一 前序遍历+排序

先将两棵树的所有节点都放到一个list中,这里可以采用各种类型的遍历(前序、中序、后序、层次);

然后将list进行排序即可。

Java

public class Problem02 {

    private List<Integer> ansList;

    private void dfs(TreeNode root) {
if (root == null) {
return;
} ansList.add(root.val);
dfs(root.left);
dfs(root.right);
} public List<Integer> getAllElements(TreeNode root1, TreeNode root2) {
ansList = new ArrayList<>();
dfs(root1);
dfs(root2);
Collections.sort(ansList);
return ansList;
} }

复杂度分析

时间复杂度:O(nlogn)。因为用到了排序。

空间复杂度:O(n)。开辟了一个m+n(跟n同量级)大小的list,m代表tree1的节点数、n代表tree2的节点数。

方法二 分别中序遍历+归并

前提:这两棵树都是二叉搜索树(BST),而一颗BST中序遍历的结果就是排好序的。

新建两个list,分别对两棵树进行中序遍历得到分别排好序的list1,list2;

已知list1和list2有序,那么将二者归并即可的到一个排好序的总list。(这里时间复杂度也就O(n))。

public class Problem02_1 {

    private void dfs(TreeNode root, List<Integer> ansList) {
if (root == null) {
return;
} dfs(root.left, ansList);
ansList.add(root.val);
dfs(root.right, ansList);
} private List<Integer> merge(List<Integer> list1, List<Integer> list2) {
List<Integer> ansList = new ArrayList<>();
int size1 = list1.size();
int size2 = list2.size();
int index1, index2;
for (index1 = 0, index2 = 0; index1 < size1 && index2 < size2;) {
int num1 = list1.get(index1);
int num2 = list2.get(index2);
if (num1 < num2) {
ansList.add(num1);
index1++;
} else {
ansList.add(num2);
index2++;
}
} while (index1 < size1) {
ansList.add(list1.get(index1++));
} while (index2 < size2) {
ansList.add(list2.get(index2++));
} return ansList;
} public List<Integer> getAllElements(TreeNode root1, TreeNode root2) {
List<Integer> ansList1 = new ArrayList<>();
List<Integer> ansList2 = new ArrayList<>();
dfs(root1, ansList1);
dfs(root2, ansList2); return merge(ansList1, ansList2);
}
}

复杂度分析

时间复杂度:O(n). 两次的中序遍历和一次的归并操作都是O(n)的时间复杂度。

空间复杂度:O(n).

方法三 遍历+优先队列

在树遍历的时候用一个优先队列(默认小根堆)来添加元素;

然后,将优先队列的元素逐个取出到list中即可。

Java

public class Problem02_2 {

    private PriorityQueue<Integer> priorityQueue;

    private void dfs(TreeNode root) {
if (root == null) {
return;
} priorityQueue.offer(root.val);
dfs(root.left);
dfs(root.right);
} public List<Integer> getAllElements(TreeNode root1, TreeNode root2) {
priorityQueue = new PriorityQueue<>();
dfs(root1);
dfs(root2);
List<Integer> ansList = new ArrayList<>();
while (!priorityQueue.isEmpty()) {
ansList.add(priorityQueue.poll());
}
return ansList;
}
}

复杂度分析

时间复杂度:O(nlogn)。因为优先队列插入和删除的操作的时间复杂度都是O(logn),然后有n节点,就是O(nlogn).

空间复杂度:O(n)

LeetCode——1305. 两棵二叉搜索树中的所有元素的更多相关文章

  1. Leetcode:1305. 两棵二叉搜索树中的所有元素

    Leetcode:1305. 两棵二叉搜索树中的所有元素 Leetcode:1305. 两棵二叉搜索树中的所有元素 思路 BST树中序历遍有序. 利用双指针法可以在\(O(n)\)的复杂度内完成排序. ...

  2. [LeetCode] Delete Node in a BST 删除二叉搜索树中的节点

    Given a root node reference of a BST and a key, delete the node with the given key in the BST. Retur ...

  3. [LeetCode] 450. Delete Node in a BST 删除二叉搜索树中的节点

    Given a root node reference of a BST and a key, delete the node with the given key in the BST. Retur ...

  4. [LeetCode]230. 二叉搜索树中第K小的元素(BST)(中序遍历)、530. 二叉搜索树的最小绝对差(BST)(中序遍历)

    题目230. 二叉搜索树中第K小的元素 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 题解 中序遍历BST,得到有序序列,返回有序序列的k-1号元素. 代 ...

  5. [LeetCode] Insert into a Binary Search Tree 二叉搜索树中插入结点

    Given the root node of a binary search tree (BST) and a value to be inserted into the tree, insert t ...

  6. LeetCode:二叉搜索树中第K小的数【230】

    LeetCode:二叉搜索树中第K小的数[230] 题目描述 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 说明:你可以假设 k 总是有效的,1 ≤ k ...

  7. LeetCode:二叉搜索树中的搜索【700】

    LeetCode:二叉搜索树中的搜索[700] 题目描述 给定二叉搜索树(BST)的根节点和一个值. 你需要在BST中找到节点值等于给定值的节点. 返回以该节点为根的子树. 如果节点不存在,则返回 N ...

  8. Leetcode 701. 二叉搜索树中的插入操作

    题目链接 https://leetcode.com/problems/insert-into-a-binary-search-tree/description/ 题目描述 给定二叉搜索树(BST)的根 ...

  9. LeetCode 230. 二叉搜索树中第K小的元素(Kth Smallest Element in a BST)

    230. 二叉搜索树中第K小的元素 230. Kth Smallest Element in a BST 题目描述 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的 ...

随机推荐

  1. HDU - 5586 Sum(区间增量最大)

    题意:将数组A的部分区间值按照函数f(Ai)=(1890*Ai+143)mod10007修改值,区间长度可以为0,问该操作后数组A的最大值. 分析:先求出每个元素的增量,进而求出增量和.通过b[r]- ...

  2. 新部署到服务器 报 The requested URL /home/profession was not found on this server. 错误

    The requested URL /home/profession was not found on this server. 通过xxx.com, 首页可以正常访问,xxx.com/xx/xx 就 ...

  3. opencv3.0机器学习算法使用

    //随机树分类Ptr<StatModel> lpmlBtnClassify::buildRtreesClassifier(Mat data, Mat responses, int ntra ...

  4. 13 —— node 获取文件属性 —— 加载第三方模块

    以加载第三方时间处理模块( moment )为例 : 一,加载 npm install moment 二,使用介绍 1,点击进入npm官网 https://www.npmjs.com/ 2,搜索 mo ...

  5. 二十六、CI框架之分页

    一.在模型中读取数据库中的表 二.在控制器中添加dividePage函数 三.在View中写入显示代码 四.查看效果,还是挺漂亮的分页效果 不忘初心,如果您认为这篇文章有价值,认同作者的付出,可以微信 ...

  6. Android自定义View——彩色圆环统计图

      1.初始化变量 圆的粗细:圆环的大小. 标注:文字前面的圆点. 分配比例大小:由于需要计算圆环扫过的角度,计算方法使用:(比例/100)*360度,用百分比算出360度占用了多少,由于比例/100 ...

  7. SAP_MM常用代码

    1.采购申请创建/修改/查看:ME51N/ME52N/ME53N 2.采购申请审批:ME54N 3.采购订单创建/修改/查看:ME21N/ME22N/ME23N 4.单个采购订单审批:ME29N 5. ...

  8. Map—数据结构

    map是数据结构的一种,map总是以key-value的形式保存数据的, 根据key来查找value的值,但是key的值是唯一的,在同一个map中不能重复. 常用的实现类java.util.hashM ...

  9. struct寻址&for反汇编

    //for 反汇编 #include<stdio.h> int main() { ; ; ;i<;i++) { s=s+; } s=; ;i>=;i--) { s=s+; } ...

  10. setoolkit+花生壳 制作钓鱼网站

    国家法律一定要遵守,知识要用在对的地方. 本贴只为了和大家交流学习,请勿用在其他地方,损害任何人的利益. 今天我,来说一下钓鱼网站 (在kali) 我们选择  1  回车 再选择 2 回车 再选择3 ...