zoukankan      html  css  js  c++  java
  • DFS习题-LeetCode

    1、Path Sum

    题目:

    Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

    Note: A leaf is a node with no children.

    Example:

    Given the below binary tree and sum = 22,

          5
         / 
        4   8
       /   / 
      11  13  4
     /        
    7    2      1
    

    return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

    分析:leetcode上一个关于DFS最简单的题目了,根据题意很容易用DFS来做,不过因为不知道树的大小,所以不能用visited数组来标识是否访问过。关键在于如何判断和为sum,第一个思路是用一个stack来保存访问过的root.val,回溯的过程就删掉最近的一个;第二个思路是每次递归都将问题化简为小子树,求和变成sum-root.val。

    1 public boolean hasPathSum(TreeNode root, int sum) {
    2         if ( root == null ) return false;
    3         TreeNode t = root;
    4         if ( t.left == null && t.right == null && sum - t.val == 0)  return true;
    5        return hasPathSum(t.left, sum - t.val )|| hasPathSum(t.right, sum - t.val);
    6 }

    和同学讨论了一下,我刚开始想的是判断左子树是否为null,不为null就递归左子树,然后再判断右子树,但是发现这样无法确定最后的return语句了。因此在做递归/DFS问题时,关于true或者false的判断一定要在最前面做,后面只是单纯的做函数的循环!这个是DFS代码的技巧,希望一定要记住。


    2、Same Tree

    题目:

    Given two binary trees, write a function to check if they are the same or not.

    Two binary trees are considered the same if they are structurally identical and the nodes have the same value.

    Example 1:

    Input:     1         1
              /        / 
             2   3     2   3
    
            [1,2,3],   [1,2,3]
    
    Output: true
    

    Example 2:

    Input:     1         1
              /           
             2             2
    
            [1,2],     [1,null,2]
    
    Output: false
    

    Example 3:

    Input:     1         1
              /        / 
             2   1     1   2
    
            [1,2,1],   [1,1,2]
    
    Output: false

    分析:这个题是要求我们判断两个数是否完全相等,当然可以从两个角度来做,一个是BFS,一个是DFS。

    BFS的话,就是遍历每一层,使用非递归的方法,大体思路要用Queue来实现,具体代码如下:

     1     public boolean isSameTree(TreeNode p, TreeNode q) {
     2 
     3         //BFS版本,用非递归实现。代码量比较冗长
     4         Queue<TreeNode> queue1 = new LinkedList<>();
     5         Queue<TreeNode> queue2 = new LinkedList<>();
     6 
     7         if ( p == null && q == null ) return true;
     8         if ( p == null || q == null ) return false;
     9         queue1.offer(p);
    10         queue2.offer(q);
    11 
    12         while ( queue1.size() > 0 && queue2.size() > 0 ){
    13             TreeNode t1 = queue1.poll();
    14             TreeNode t2 = queue2.poll();
    15             if ( t1.val != t2.val ) return false;
    16             if ( t1.left != null && t2.left != null ){
    17                 queue1.offer(t1.left);
    18                 queue2.offer(t2.left);
    19             }
    20             if ( t1.left == null && t2.left != null ) return false;
    21             if ( t1.left != null && t2.left == null ) return false;
    22 
    23             if ( t1.right != null && t2.right != null ){
    24                 queue1.offer(t1.right);
    25                 queue2.offer(t2.right);
    26             }
    27             if ( t1.right == null && t2.right != null ) return false;
    28             if ( t1.right != null && t2.right == null ) return false;
    29         }
    30         return true;
    31 }

    可以看到用BFS出现了大量的代码重用,多余空间,效率确实不高,在leetcode上运行需要6ms,主要问题就是不简洁,可读性不高

    那么用DFS来实现就简单的多,因为使用递归,所以代码很简洁。DFS使用一定要注意只关注当前状态而不去考虑之前或者之后的状态。这个理论在判断递归结束条件的时候非常有用。在本题中,判断true的条件就是搜索到叶子节点,代码如下:

    1 public boolean isSameTree(TreeNode p, TreeNode q) {
    2     if ( p == null && q == null ) return true;
    3     if ( p == null || q == null ) return false;
    4     if ( p.val != q.val ) return false;
    5     return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    6 }

    注意,这里return true并不是返回最后的结果,只是返回当前状态对应的状态结果。


    3、Minmum Depth of Binary Tree

    题目:

    Given a binary tree, find its minimum depth.

    The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.

    Note: A leaf is a node with no children.

    Example:

    Given binary tree [3,9,20,null,null,15,7],

        3
       / 
      9  20
        /  
       15   7

    return its minimum depth = 2.

    分析:求二叉树的最小高度,显然用DFS来做。分析过程如下:

    这里理解了一下递归的思想,递归是将大问题不断转化成小的问题,关键是找到递归结束条件和递归时机。代码如下:

     1     public int minDepth(TreeNode root) {
     2         if ( root == null ) return 0;
     3         return DFS(root);
     4     }
     5     public int DFS(TreeNode root) {
     6         if ( root.left == null && root.right == null ) return 1;   //找到一个叶子节点,那么叶子节点就是1层
     7         if ( root.left == null ) {
     8             return DFS(root.right) + 1;
     9         }
    10         if ( root.right == null ) {
    11             return DFS(root.left) + 1;
    12         }
    13         return Math.min(DFS(root.left), DFS(root.right)) + 1;
    14     }
  • 相关阅读:
    实现三联tab切换特效
    SQL Server对数据进行添加
    SmartUpload实现文件上传
    JavaScript图片轮播,举一反三
    SQL Server对数据进行删除
    用SQL Server查询所有数据并显示
    SQL Server日期格式化
    用SQL Server验证用户名和密码
    SQL Server存储过程作业(三)
    SQL Server存储过程作业(二)
  • 原文地址:https://www.cnblogs.com/boris1221/p/9222046.html
Copyright © 2011-2022 走看看