LeetCode刷题记录-简单模块(三)

目录

        • 相同的树(深度优先搜索、广度优先搜索)
        • 对称二叉树(深度优先搜索、广度优先搜索)
        • 二叉树的最大深度
        • 将有序数组转换为平衡二叉树
        • 判断二叉树是不是平衡二叉树(递归)
        • 二叉树的最小深度
        • 路径总和

相同的树(深度优先搜索、广度优先搜索)

给定两个二叉树的根节点,判断两棵树是否完全相同

对两棵树使用相同的方式遍历比较即可

  • 深度优先搜索
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
       //按照同样的顺序遍历两个树 然后对比
        if(p == null && q == null){
            return true;
        }
        if((p == null || q == null) || p.val != q.val){
            return false;
        }
        return tdoTrav(p.left , q.left) && doTrav(p.right , q.right);
    }
}
  • 广度优先搜索
    二叉树的遍历方法一般是按照深度有限的原则,但是可以使用队列来实现广度优先的搜索,即按照树的层数一层一层的向下搜索
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
    	//使用队列作为暂存
        LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
        while( !(queue.size()== 0  && p == null && q == null)){
            if(p == null && q == null){
                p = queue.poll();
                q = queue.poll();
                continue;
            }
            if(p == null || q == null || p.val != q.val){
                return false;
            }
            queue.add(p.left);
            queue.add(q.left);
            queue.add(p.right);
            queue.add(q.right);
            p = null;
            q = null;
        }
        return true;
    }
}

对称二叉树(深度优先搜索、广度优先搜索)

给定一个二叉树,判断该二叉树是不是轴对称的
  • 取出root节点的左子节点和右子节点,对两棵子树进行深度优先遍历
class Solution {
    public boolean isSymmetric(TreeNode root) {
        //将树分为两棵树 完成后查看两棵树是否相同 使用深度优先检索
        if(root == null){
            return true;
        }
        return doTrav(root.left , root.right);

    }
    
    public boolean doTrav(TreeNode a , TreeNode b){
        if(a == null && b == null){
            return true;
        }
        if(a == null || b == null){
            return false;
        }
        if(a.val != b.val){
            return false;
        }
        //注意 这里不是比较两棵树是否是相同树,而是根据轴进行对称
        return doTrav(a.left , b.right) && doTrav(a.right , b.left);
    }
}
  • 广度优先遍历root节点的两子树
class Solution {
    public boolean isSymmetric(TreeNode root) {
        //使用迭代法处理 这里使用广度优先检索
        if(root == null){
            return true;
        }
        TreeNode p = root.left;
        TreeNode q = root.right;
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        while(!(queue.isEmpty() && p == null && q == null)){
            if(p == null && q == null){
                p = queue.poll();
                q = queue.poll();
                continue;
            }
            if(p == null || q == null || p.val != q.val){
                return false;
            }
            queue.add(p.left);
            queue.add(q.right);
            queue.add(p.right);
            queue.add(q.left);
            p = null;
            q = null;
        }
        return true;
    }
    
}

二叉树的最大深度

给定一个二叉树,请求出该二叉树的最大深度
  • 深度优先遍历(递归调用)
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        //递归处理 整个二叉树的最大深度为根节点加上max(左子树最大深度,右子树最大深度)
        if(root == null){
            return 0;
        }
        return 1 + Math.max(maxDepth(root.left) ,maxDepth(root.right));
    }
}
  • 广度优先遍历
    同样可以使用队列来处理遍历,但是只有将当前层的节点全部处理完毕后才能继续向下层遍历。
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        //广度优先遍历
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(root);
        int depth = 0;
        while(!queue.isEmpty()){
            int size = queue.size();
            while(size > 0){
                root = queue.poll();
                if(root.left != null){
                    queue.add(root.left);
                }
                if(root.right != null){
                    queue.add(root.right);
                }
                size-- ;
            }
            depth ++;
        }
        return depth;
    }
}

将有序数组转换为平衡二叉树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
  • 递归法处理
    因为给定的是有序数组,因此使用二分法找到每一段的中值作为节点即可
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        TreeNode root = new TreeNode();
        doGetMid(root,nums , 0 , nums.length - 1);
        return root;
    }

    public void doGetMid(TreeNode root, int[] nums , int head , int tail){
        int tempMid =  head + (tail - head) / 2;
        root.val = nums[tempMid];
        if(tempMid - 1 >= head){
            root.left = new TreeNode();
            doGetMid(root.left , nums ,head , tempMid - 1 );
        }
        if(tempMid + 1 <= tail){
            root.right = new TreeNode();
            doGetMid(root.right , nums , tempMid + 1 , tail);
        }
    }
}

判断二叉树是不是平衡二叉树(递归)

给定一个二叉树,当某个节点的左右子树之间的高度差大于1时,该二叉树不是平衡二叉树
  • 由顶至尾递归遍历(时间复杂度O(n2)
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //确实纯想象的话是一个比较蠢的方法 因为有很多次递归 并且递归套递归
    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return true;
        } else {
            return Math.abs(height(root.left) - height(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
        }
    }

    public int height(TreeNode root) {
        if (root == null) {
            return 0;
        } else {
            return Math.max(height(root.left), height(root.right)) + 1;
        }
    }
}
  • 由尾至顶递归遍历(时间复杂度O(n)
    方法一由于是自顶向下递归,因此对于同一个节点,函数会被重复调用,导致时间复杂度较高。如果使用自底向上的做法,则对于每个节点,函数只会被调用一次。
    自底向上递归的做法类似于后序遍历,对于当前遍历到的节点,先递归地判断其左右子树是否平衡,再判断以当前节点为根的子树是否平衡。如果一棵子树是平衡的,则返回其高度(高度一定是非负整数),否则返回 -1−1。如果存在一棵子树不平衡,则整个二叉树一定不平衡。
class Solution {
    public boolean isBalanced(TreeNode root) {
        return height(root) >= 0;
    }

    public int height(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftHeight = height(root.left);
        int rightHeight = height(root.right);
        if (leftHeight == -1 || rightHeight == -1 || Math.abs(leftHeight - rightHeight) > 1) {
            return -1;
        } else {
            return Math.max(leftHeight, rightHeight) + 1;
        }
    }
}

二叉树的最小深度

给定一个二叉树,请找出该二叉树的最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。

只需要确定一点,当该节点没有左右子树时,可以认定为叶子节点。找出最近的叶子节点即可。

  • 广度优先遍历
class Solution {
    public int minDepth(TreeNode root) {
        //尝试使用广度优先遍历处理
        if(root == null){
            return 0;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        int minDepth = 1;
        queue.add(root);
        while(root != null || !queue.isEmpty()){
            int size = queue.size();
            while(size > 0){
                root = queue.poll();
                if(root.left == null && root.right == null){
                    return minDepth;
                }else{
                    if(root.left != null){
                        queue.add(root.left);
                    }
                    if(root.right != null){
                        queue.add(root.right);
                    }
                }
                size--;
            }
            minDepth++;
        }
        return minDepth;
    }
}
  • 深度优先遍历
class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }

        if (root.left == null && root.right == null) {
            return 1;
        }

        int min_depth = Integer.MAX_VALUE;
        if (root.left != null) {
            min_depth = Math.min(minDepth(root.left), min_depth);
        }
        if (root.right != null) {
            min_depth = Math.min(minDepth(root.right), min_depth);
        }

        return min_depth + 1;
    }
}

路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。
判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。
如果存在,返回 true ;否则,返回 false 。
  • DFS回溯算法
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root == null){
            return false;
        }
        targetSum -= root.val;
        if(root.left == null && root.right == null){
            if(targetSum != 0){
                return false;
            }else{
                return true;
            }
        }
        return hasPathSum(root.left , targetSum) || hasPathSum(root.right , targetSum) ;
    }
}

你可能感兴趣的:(LeetCode刷题记录,leetcode,算法,深度优先)