剣はオファー34を指します。特定の値に合計されるバイナリツリー内のパス
タイトル説明
問題解決のアイデア
なおleetcode 46. 全排列
、leetcode 78. 子集
、leetcode 77. 组合
違いをバックトラック、両方の選択リストが同じで、すべての子ノード、ある記録モードのパスでの主な違いのうそ、このレコードは、子供たちが記録されている根本的な問題、です。
-
上記の3つのバックトラッキングの質問では、ノードが複数の選択肢に直面するたびに、選択肢の1つが行われると、子ノードの選択肢がパスに追加されます。ルートノードは空であるため、最初の選択はルートノードの子ノードから行われます。
したがって、選択を行って選択をキャンセルする操作はforループにあります。つまり、子供を訪問するたびに選択をキャンセルする必要があります。この方法でトラバースした後、ルートノードの訪問のみが無視されます。 -
この質問(他の二分木、グラフ、およびdpの再帰的なアイデアを含む)を選択すると、現在選択されているノードがパスに追加されます。
したがって、選択を行って選択をキャンセルする操作はforループの外側にあります。つまり、すべての子が訪問された後、ルートノードの選択は1回キャンセルされます。この方法でトラバースした後、ツリー全体(ルートノードを含む)にアクセスします。
完全なコード:
class Solution {
public List<List<Integer>> res = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int target) {
if (root == null) return res;
LinkedList<Integer> track = new LinkedList<>();
backtrack(root, target, track);
return res;
}
//定义:打印出从root节点一直到叶子节点的路径和为target的路径
public void backtrack(TreeNode root, int target, LinkedList<Integer> track) {
//空节点直接返回
if (root == null) return;
// 到达叶节点
if (root.left == null && root.right == null && target == root.val) {
track.add(root.val);
res.add(new LinkedList<>(track));
track.removeLast();
return;
}
track.add(root.val);
//在已将root添加进路径的基础上,分别打印出左右子树的路径
backtrack(root.left, target - root.val, track);
backtrack(root.right, target - root.val, track);
track.removeLast();
}
}