问题描述: 二叉树如图,求和为11的路径列表。
(比如:和为11的路径有 [[1,2,3,5],[1,4,6]])
先说明一下,之前大学在学数据结构的时候是学过二叉树的遍历的,但是有些忘记了(得补上),用上二叉树遍历的话应该会简单些。这里是我根据实际问题自己想的一个方法。
首先,先把问题聚焦在一个叉上,比如说2-1-4这个节点,对于1这个节点来说,有三种情况,
1:一个子节点都没有;
2:有一个左节点;
3:有一个右节点。
如果是叶子节点的话,那么把当前节点加入路径里面成为一个路径的结束,成为一个结果([1])。如果不是叶子节点的话,那么就要继续往下面遍历,有左右两个节点,所以路径肯定不一样,所以每遍历到一个左右都有的子节点的时候,就需要新建一个包含根节点以及根节点以前的节点路径的路径,分别把左右节点加进去形成两个路径([1-2],[1-4])。到这里,递归的原子操作就出来了:
1:一个子节点都没有,把当前的形成的路径结果加入结果集;
2:有一个左节点,把左节点加入路径,然后把左节点当根节点进行下一次递归;
3:有一个右节点,把右节点加入路径,然后把右节点当根节点进行下一次递归;
/** * @param node 根节点 * @param nodeList 到根节点为止已经形成的路径 * @param pathList 存储所有路径结果的结果集 */ private void leftRight(TreeNode node, List<Integer> nodeList, List<List<Integer>> pathList) { if (node.left==null && node.right==null){ pathList.add(nodeList); } if(node.right!=null){ /**如果右节点不为空*/ List nodeList2 = new ArrayList(); nodeList2.addAll(nodeList); /**把当前节点的路径复制一份*/ nodeList2.add(node.right.val); /**加入右节点的值路径*/ if(node.right.left==null && node.right.right==null){ pathList.add(nodeList2); /**如果右节点是个叶子节点,就把这个路径放入结果集*/ }else{ leftRight(node.right,nodeList2,pathList); /**如果右节点不是叶子节点,进行下一次递归*/ } } if(node.left!=null){ nodeList.add(node.left.val); /**遍历的左节点都用参数传进来的list,不新建路径列表(使用参数的节点处理得放在后面,因为处理完之后参数会被改变)*/ if(node.left.left==null && node.left.right==null){ pathList.add(nodeList); /**如果左节点是个叶子节点,就把这个路径放入结果集*/ }else{ leftRight(node.left, nodeList,pathList); /**如果左节点不是叶子节点,进行下一次递归*/ } } }
关键的代码就是这个,等到这个递归方法执行完,存储所有路径结果的结果集pathList里面的数据就是根节点到每个叶子节点的路径集合,然后遍历这个集合,把符合要求的路径筛选出来就大功告成了。