随想录训练营Day20 | 第六章 二叉树 part06 617.合并二叉树, 700.二叉搜索树中的搜索,98.验证二叉搜索树
标签: LeetCode闯关记
617.合并二叉树
- 递归(各类遍历顺序均可)
//同时操作两棵树
//思路:不新建树,在原树tree1的基础上修改值
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1 == null){
return root2;
}
if(root2 == null){
return root1;
}
root1.val += root2.val;
root1.left = mergeTrees(root1.left,root2.left);
root1.right = mergeTrees(root1.right, root2.right);
return root1;
}
}
- 迭代法:用栈
//同时操作两棵树
//思路:不新建树,在原树tree1的基础上修改值
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1 == null){
return root2;
}
if(root2 == null){
return root1;
}
Deque<TreeNode> deque = new ArrayDeque<>();
deque.add(root2);
deque.add(root1);
while(! deque.isEmpty()){
TreeNode node1 = deque.pollFirst();
TreeNode node2 = deque.pollFirst();
node1.val += node2.val;
//注意入栈顺序和出栈顺序
if(node2.right != null && node1.right != null){//先入栈右子树,这样出栈的时候能够先出左子树
deque.add(node2.right);//先入栈tree2 的节点,再入tree1, 这样先弹出tree1;
deque.add(node1.right);
}else{
if(node1.right == null){
node1.right = node2.right;
}//如果是node2.right == null, 就不用处理,因为此时只需要遍历node1.right
}
if(node2.left != null && node1.left != null){
deque.add(node2.left);
deque.add(node1.left);
}else{
if(node1.left == null){
node1.left = node2.left;
}//如果是node2.right == null, 就不用处理,因为此时只需要遍历node1.right
}
}
return root1;
}
}
700. 二叉搜索树中的搜索
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
Deque<TreeNode> deque = new LinkedList<>();
deque.add(root);
while (! deque.isEmpty()){
TreeNode node = deque.pop();
if(node.val == val){
System.out.println(node);
return node;
}
if(node.val > val && node.left != null){
deque.add(node.left);
}else if(node.val < val && node.right != null){
deque.add(node.right);
}
}
return null;
}
}
}
算法分析
| 算法 | 时间复杂度 | 空间复杂度 | 是否在原数据上修改 | 是否稳定 |
|---|---|---|---|---|
| searchBST(迭代法) | O(h) | O(h) | 否 | 是 |
| 其中,h是树的高度。 |
时间复杂度为O(h),其中h是树的高度。因为在最坏情况下,需要遍历树的所有节点。空间复杂度也是O(h),因为需要用一个栈来存储访问过的节点,最坏情况下需要存储整棵树的节点。这个算法不会在原数据上进行修改,且由于二叉搜索树的特点,相同元素的顺序不会被改变,因此算法是稳定的。
98.验证二叉搜索树
class Solution {
TreeNode pre = null;
public boolean isValidBST(TreeNode root) {
if(root == null){
return true;
}
boolean left = isValidBST(root.left);
if(pre != null && root.val <= pre.val){//注意pre的使用,以及第一次比较时,pre为null的处理方法
return false;
}else{
pre = root;
}
boolean right = isValidBST(root.right);
return left && right;
}
}
| 时间复杂度 | 空间复杂度 |
|---|---|
| O(n) | O(h) |
| 时间复杂度:遍历二叉树的每一个节点,时间复杂度为O(n)。 | |
| 空间复杂度:递归调用栈的深度最大为二叉树的高度h,因此空间复杂度为O(h)。 |
- 迭代法
错解:只比较了节点和它的左右孩子的大小关系,但是例如[5,4,6,null,null,3,7],便没有考虑3和5的大小关系
class Solution {
TreeNode pre = null;
public boolean isValidBST(TreeNode root) {
if(root == null){
return true;
}
Deque<TreeNode> deque = new LinkedList<>();
deque.add(root);
while (! deque.isEmpty()){
TreeNode node = deque.pop();
if(node.left != null){
deque.add(node.left);
if(node.val <= node.left.val){
return false;
}
}
if(node.right != null){
deque.add(node.right);
if(node.val >= node.right.val){
return false;
}
}
}
return true;
}
}