1. 程式人生 > >劍指Offer 面試題34:二叉樹中和為某一值的路徑 Java程式碼實現

劍指Offer 面試題34:二叉樹中和為某一值的路徑 Java程式碼實現

題目:輸入一棵二叉樹和整數,打印出二叉樹中節點值得和為輸入整數的所有路徑。從樹的根節點開始往下一直到葉節點所經過的節點形成一條路徑。

解題思路:路徑從根節點開始,應該用類似於前序遍歷的方式訪問樹節點。我們需要整個路徑,就需要一個容器儲存經過路徑上的節點,以及一個變數記錄當前已有節點元素的和。當前序遍歷到某一個節點時,新增該節點到路徑,累加節點值。如果該節點為葉子節點並節點值累計等於目標整數,則找到一條路徑。如果不是葉子節點,則繼續訪問子節點。一個節點訪問結束後,遞迴函式自動回到其父節點。

public class Problem34 {
	// pathList存所有可能路徑
	// path用來儲存路徑的資料結構 這兒用ArrayList模擬了棧的資料結構
	private ArrayList<ArrayList<Integer>> pathList = new ArrayList<ArrayList<Integer>>();
	private ArrayList<Integer> path = new ArrayList<>();

	public ArrayList<ArrayList<Integer>> findPath(TreeNode root, int sum) {
		if (root == null)
			return pathList;
		path.add(root.val);
		sum -= root.val;
		// 路徑值等於0,且當前節點是葉子節點 則找到一條路徑
		if (sum == 0 && root.left == null && root.right == null)
			// 每次找到路徑都需要新增一個新的path 不可以直接加path成員變數 這是個引用,不然所有pathList的值都指向同一個path
			pathList.add(new ArrayList<Integer>(path));
		if (root.left != null)
			findPath(root.left, sum);

		if (root.right != null)
			findPath(root.right, sum);
		// 訪問完當前節點 需要刪除路徑中最後一個節點,回退至父節點
		path.remove(path.size() - 1);
		return pathList;
	}

	public static void main(String[] args) {
		TreeNode node1 = new TreeNode(10);
		TreeNode node2 = new TreeNode(5);
		TreeNode node3 = new TreeNode(12);
		TreeNode node4 = new TreeNode(4);
		TreeNode node5 = new TreeNode(7);

		node1.left = node2;
		node1.right = node3;

		node2.left = node4;
		node2.right = node5;

		Problem34 p34 = new Problem34();
		System.out.println(p34.pathList);
		p34.findPath(node1, 22);
		for (ArrayList<Integer> list : p34.pathList) {
			for (int i : list) {
				System.out.print(i + " ");
			}
			System.out.println();
		}
	}
}
[]
10 5 7 
10 12