1. 程式人生 > >刷題:輸入一顆二叉樹和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。

刷題:輸入一顆二叉樹和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。

原題:輸入一顆二叉樹和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。路徑定義為從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。

思路分析:首先思考節點值的和為輸入的整數,每條路徑都一定是從根節點到葉子節點,在資料結構中從根節點到葉子節點的遍歷稱之為深度優先遍歷DFS。因此整個過程可以採用先序遍歷方式的DFS,即根節點》左子樹》右子樹。隨後考慮一次遍歷完成後的處理,當一次遍歷完成後,如果輸入整數值恰好等於節點值之和,則輸出這條路徑並且回退一個節點;如果不等於則直接回退一個節點,即回退到當前節點的父節點,如果該父節點有右孩子,則繼續遍歷,否則繼續回退。考慮回退到根節點,此時如果它有右孩子,則繼續遍歷,否則整個DFS結束。

資料結構分析:使用java完成整個題目,採用ArrayList<ArrayList<Integer>>,舉個如下的例子,輸入整數為22。


第一次遍歷 10,5,4   19<22,因此ArrayList要使用remove函式回退到父節點5上,開始尋找右孩子。

第二次遍歷 10,5,7   22=22,此時正好輸出這條路徑(將路徑新增到ArrayList中),10,5,7,回退到父節點5上,此時5的左右孩子都已遍歷完成,因此回退到父節點10

第三次遍歷 10,12   22=22,此時正好輸出這條路徑(將路徑新增到

ArrayList中,10,12,由於12沒有左右孩子,因此直接回退到父節點10

由於根節點10左右孩子都已遍歷完成,因此整個DFS結束。

需要注意的是不論路徑的值是否等於輸入整數值,都要回退,即使用remove函式移除路徑上的最後一個節點。

java程式碼如下:

import java.util.ArrayList;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    ArrayList<ArrayList<Integer>> pathList = new ArrayList<ArrayList<Integer>>();
    ArrayList<Integer> path = new ArrayList<Integer>();
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
          if(root == null)
              return  pathList; 
          path.add(root.val);
          if(root.left == null && root.right == null && target == root.val)
          {
                pathList.add(new ArrayList<Integer>(path));
          }
          if(root.val <= target && root.left != null){
              FindPath(root.left,target-root.val); 
          }  
          if(root.val <= target && root.right != null)
          {
              FindPath(root.right,target-root.val); 
          }   
          path.remove(path.size()-1);//回退到父節點
          return pathList;
    }
}
因為自己這個問題磨了一段時間,自己把理解放在這裡,如果後續遇到類似問題可以參考。