1. 程式人生 > >LeetCode---113.路徑總和II

LeetCode---113.路徑總和II

題目來源:https://leetcode-cn.com/problems/path-sum-ii/description/

題目描述:

演算法描述:

1.該題是上篇部落格的升級版。詳情請見https://blog.csdn.net/qq_39241239/article/details/82749696 

2.該題比較上一題的難度在於需要輸出每一條路徑。所以該題應該採用回溯演算法。

3.首先需要一個結果集合list用來存放最終所有路徑。還需要一箇中間集合arrlist用來存放一條路徑。

4.每當遍歷到一個結點的時候,先將該結點的值加入中間集合中。如果當前節點沒有子女並且到該結點的路徑符合要求,就將這個中間集合加入到結果集合當中。如果該結點有左子樹,就遍歷左子樹。如果該結點有右子樹那麼就遍歷右子樹。

5.需要注意的是,當遍歷完一條路徑(不論該路徑是否符合要求)回到函式呼叫的地方時,都要將中間集合最後一個元素刪除(這裡就體現出了回溯)。

程式碼如下:

class Solution {
	public List<List<Integer>> pathSum(TreeNode root, int sum) {
		//定義一個結果集合
		List<List<Integer>> list = new ArrayList<>();
		if (root == null) {
			return list;
		}
		//定義一箇中間集合
		ArrayList<Integer> arrlist = new ArrayList<>();
		path(root, list, arrlist, sum);
		return list;
	}

	public void path(TreeNode root, List<List<Integer>> list, ArrayList<Integer> arrlist, int nowSum) {
		//將當前節點的值加入中間集合中
		arrlist.add(root.val);
		nowSum -= root.val;
		if (root.left == null && root.right == null) {
			if (nowSum == 0) {
				//如果當前節點無子女,就判斷該路徑是否符合要求,如果符合那麼就將該路徑加入結果集合中
				list.add(new ArrayList<Integer>(arrlist));
			}
			//遍歷完一條路徑就回到呼叫點,這裡也可以不寫return,也會自動返回。但是加return可以略微提高效率。
			return;
		}
		if (root.left != null) {
			//左子樹不為空就遞迴遍歷左子樹,要注意的是函式返回後,要將中間集合最後一個元素刪除(這裡體現了回溯)
			path(root.left, list, arrlist, nowSum);
			arrlist.remove(arrlist.size() - 1);
		}
		if (root.right != null) {
			//右子樹不為空就遞迴遍歷右子樹,要注意的是函式返回後,要將中間集合最後一個元素刪除(這裡體現了回溯)
			path(root.right, list, arrlist, nowSum);
			arrlist.remove(arrlist.size() - 1);
		}
	}
}