随想录训练营Day20 | 第六章 二叉树 part06 617.合并二叉树, 700.二叉搜索树中的搜索,98.验证二叉搜索树

98 阅读1分钟

随想录训练营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;
    }
}