http://blog.csdn.net/jackey_jk/article/details/51033830
1. Spiral/Zigzag Level Order traversal:
参考自:http://www.java2blog.com/2014/08/spiralzigzag-level-order-traversal-of.html
代码实现以S形遍历一个二叉树,效果如下图:
思路:看到这个图会联想到BFS,只是BFS中每层都以从左到右的顺序遍历,而此图每层会改变一次方向。所以我们需要1.一个判断本层该向左还是向右遍历的标识变量;2.根据表示变量,按一定顺序保存每行各个元素的容器。然后问题是怎样每向下一层就改变一次表示变量。
方法是利用两个Stack数据结构,其中一个为临时Stack每向下遍历一层就重新创建并且按规定顺序保存下一层的节点;另一个用来处理上一个临时Stack保存下来的数据,并且每处理完一个临时Stack就改变一次表示变量。代码如下:
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> static <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> spiralOrZigzagLevelOrder(TreeNode root) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(root<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">==</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Stack</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>TreeNode<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">stack</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Stack</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>TreeNode<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span>(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//办事Stack</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">stack</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>push(root); boolean directionflag<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//记录方向的表示变量</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">stack</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>isEmpty()) { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Stack</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>TreeNode<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> tempStack<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Stack</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>TreeNode<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span>(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//临时Stack</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">stack</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>isEmpty()) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此循环内都是同一层节点操作</span> { TreeNode tempNode<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">stack</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>pop(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//弹出并打印一个节点</span> System<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>out<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>printf(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"%d "</span>,tempNode<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">data</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!</span>directionflag) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//flag初始为false,第一次存下一层(第二层)节点时以从右到左为顺序</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//所以存入Stack时先存左再=后存右(后进先出)</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(tempNode<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>left<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">null</span>) tempStack<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>push(tempNode<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>left); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(tempNode<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>right<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">null</span>) tempStack<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>push(tempNode<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>right); }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(tempNode<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>right<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">null</span>) tempStack<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>push(tempNode<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>right); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(tempNode<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>left<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">null</span>) tempStack<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>push(tempNode<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>left); } } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此时一层节点处理完毕</span> directionflag<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=!</span>directionflag; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//改变方向</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">stack</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>tempStack; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将存好下一层节点的临时Stack交给办事Stack</span> } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li></ul>
2. Path Sum:
给一个二叉树和一个int sum,判断是否有一个从根节点到末端节点的路径,使得路径从头到尾所有节点的值相加等于sum。
例如如下的二叉树,和sum = 21,
我们发现8-5-7-1这条路径四个节点相加为21 所以返回true。
思路:从根节点到末端节点很容易想到深度优先。如果考虑创建一个新的int累加路径上的节点值,然后对比sum,那么问题会变得很复杂,因为一条路径不行需要减去节点值重新累加。所以方法是从sum中减去节点值,使用迭代,预先判断路径末端节点是否符合要求,代码如下。
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Solution</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">hasPathSum</span>(TreeNode root, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> sum) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(root==<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(root.left==<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && root.right==<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> sum==root.val; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (hasPathSum(root.left, sum-root.val) || hasPathSum(root.right, sum-root.val)); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>
3. Minimum Depth of Binary Tree:
给一个二叉树,求出其中的最短路径。
思路:求最短的路径,第一想法是只要从上至下遍历出每个路径的长度,返回最短的即可。答案与此思路也类似,广度优先和深度优先都可以解决此题。
广度优先:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">minDepth</span>(TreeNode root) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(root==<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//1</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(root.left!=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && root.right !=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> + Math.min(minDepth(root.left), minDepth(root.right)); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//2</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> + minDepth(root.left) + minDepth(root.right); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//3</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//最后一行中minDepth(root.left)和minDepth(root.right)至少一个为0</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
广度优先的代码看似复杂,其实原理很简单,从根节点开始向下访问,每个访问的节点有三种可能的情况:
–若访问节点左右子都存在(运行//2),取左右子中包含的更短路径并+1,+1是因为它有子节点;
–若访问的节点左右子至少有一个不存在(运行//3),路径+1并且继续访问其子节点(因为它有子,所以肯定不在末端);
–若访问节点为空,返回0,因为它不占长度。
叙述起来比较拗口,画一个简单地二叉树,对照代码很容易想清楚。
深度优先:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> min = Integer.MAX_VALUE; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//初始化一个int</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">minDepth</span>(TreeNode root) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (root ==<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>){ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; } dfs(root,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此时根节点非空,最小长度至少为1,带入计算</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> min; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">dfs</span>(TreeNode node, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> height){ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (node.left!=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> ) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//左子非空,带入左子且长度+1</span> dfs(node.left, height + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(node.right !=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>){ <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//右子同理</span> dfs(node.right,height+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (node.left == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && node.right==<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>){ <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此时访问到末端节点,若得出的长度比当前min小,赋给min</span> min = Math.min(min,height); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul>
4. Binary Tree Paths
给一个二叉树,将其从根到末梢的所有路径保存到List里。例如二叉树[1,2,3],返回List形式为{“1->2”,”1->3”}。
思路:路径问题很容易联想到深度优先。于是我们继续分析:1. 对于每个路径我们需要一个String保存从根到末梢的所有点,也就是说每个路径就是一个String,我们可以到末梢点的时候(左右子都为空)将它存进List;2. 对于最后一个末梢点,它后面没有”->”字符,所以也要特殊处理;3. 用String直接相加会占用很大内存,所以考虑使用StringBuilder。
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> List<String> <span class="hljs-title" style="box-sizing: border-box;">binaryTreePaths</span>(TreeNode root) { List<String> res = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<>(); StringBuilder path = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> StringBuilder(); helper(root,path,res); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> res; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">helper</span>(TreeNode root, StringBuilder path, List<String> res){ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(root==<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> len = path.length(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//记录添加此节点前的字符长度</span> path.append(root.val); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(root.left==<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span> && root.right==<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>){ res.add(path.toString()); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{ path.append(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"->"</span>); helper(root.left,path,res); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//1</span> helper(root.right,path,res); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//2</span> } path.setLength(len); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此行意义在于运行//1之后遇到末梢节点,此时继续运行//2的话,</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//path中已被添加了刚刚的末梢节点,所以再添加末梢节点后,</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//截掉该末梢节点,继续运行//2</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//否则会生成"1->23"这样的结果</span> }</code>