本系列導航:劍指offer(第二版)java實現(xiàn)導航帖
面試題34:二叉樹中和為某一值的路徑
題目要求:
輸入一棵二叉樹和一個整數(shù),打印出二叉樹中節(jié)點值的和為輸入整數(shù)的所有路徑罐呼。從樹的根節(jié)點開始往下一直到葉節(jié)點所經(jīng)過的節(jié)點形成一條路徑侦高。
解題思路:
需要得到所有從根節(jié)點到葉節(jié)點的路徑,判斷和是否為給定值。自己寫一個小的二叉樹瞧壮,通過模擬上述過程咆槽,發(fā)現(xiàn)獲取所有路徑的過程與前序遍歷類似秦忿。
因此灯谣,可以對給定二叉樹進行前序遍歷酬屉。當被訪問節(jié)點時葉節(jié)點時揍愁,判斷路徑和是否為給定值。此外朽缎,為了記錄路徑上的節(jié)點话肖,需要一個數(shù)組。
package chapter4;
import structure.TreeNode;
import java.util.ArrayList;
import java.util.List;
/**
* Created by ryder on 2017/7/18.
* 二叉樹中和為某一值的路徑
*/
public class P182_FindPath {
//用類似于前序遍歷的思路解決
public static void findPath(TreeNode<Integer> root,int exceptedSum){
if(root==null)
return;
List<Integer> path = new ArrayList<>();
findPath(root,path,exceptedSum,0);
}
//curNode為將要被訪問的節(jié)點葡幸,還未被加入到path中
public static void findPath(TreeNode<Integer> curNode,List<Integer> path,int exceptedSum,int currentSum){
path.add(curNode.val);
currentSum+=curNode.val;
if(curNode.left!=null)
findPath(curNode.left,path,exceptedSum,currentSum);
if(curNode.right!=null)
findPath(curNode.right,path,exceptedSum,currentSum);
if(curNode.left==null && curNode.right==null && currentSum==exceptedSum)
System.out.println(path);
path.remove(path.size()-1) ;
}
public static void main(String[] args) {
// 10
// / \
// 5 12
// / \
// 4 7
TreeNode<Integer> root = new TreeNode<Integer>(10);
root.left = new TreeNode<Integer>(5);
root.right = new TreeNode<Integer>(12);
root.left.left = new TreeNode<Integer>(4);
root.left.right = new TreeNode<Integer>(7);
findPath(root,22);
findPath2(root,22);
}
}
如果二叉樹的所有節(jié)點值都是大于0的(原題中并沒有這個條件)最筒,可以進行剪枝。
//如果所有節(jié)點值均大于0蔚叨,可進行剪枝
public static void findPath2(TreeNode<Integer> root,int exceptedSum){
if(root==null)
return;
List<Integer> path = new ArrayList<>();
findPath2(root,path,exceptedSum,0);
}
//curNode為將要被訪問的節(jié)點床蜘,還未被加入到path中
public static void findPath2(TreeNode<Integer> curNode,List<Integer> path,int exceptedSum,int currentSum){
path.add(curNode.val);
currentSum+=curNode.val;
//只有當currentSum小于exceptedSum時需要繼續(xù)當前節(jié)點的子節(jié)點的遍歷
if(currentSum<exceptedSum){
if(curNode.left!=null)
findPath2(curNode.left,path,exceptedSum,currentSum);
if(curNode.right!=null)
findPath2(curNode.right,path,exceptedSum,currentSum);
}
//currentSum大于等于exceptedSum時可以直接停止當前分支的遍歷,因為當前分支下currentSum只會越來越大蔑水,不會再有符合要求的解
else if(currentSum==exceptedSum && curNode.left==null && curNode.right==null)
System.out.println(path);
path.remove(path.size()-1) ;
}
運行結(jié)果
[10, 5, 7]
[10, 12]
[10, 5, 7]
[10, 12]