DFS习题-LeetCode
Posted Lin.B
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于DFS习题-LeetCode的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode207.课程表 | BFS DFS 邻接表 邻接矩阵
LeetCode207.课程表 | BFS DFS 邻接表 邻接矩阵
LeetCode207.课程表 | BFS DFS 邻接表 邻接矩阵
LeetCode207.课程表 | BFS DFS 邻接表 邻接矩阵