本文是在學習中的總結,歡迎轉載但請註明出處:http://blog.csdn.net/pistolove/article/details/41910495
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
For example:Given the below binary tree and
sum = 22
,5 / \ 4 8 / / \ 11 13 4 / \ \ 7 2 1
return true, as there exist a root-to-leaf path 5->4->11->2
which sum is 22.
思路:
(1)題意爲給定一個(每個節點帶有數值)二叉樹和一個整數,判斷在二叉樹中是否存在從樹根到葉子節點路徑使得路徑之和等於給定的整數。
(2)我覺得該題主要考察對常用數據結構"棧"的熟悉和使用。包括棧的主要特性:先進後出、棧的peek()方法、棧的pop()方法、棧的push()方法。
(3)首先,通過分析可知,要想獲取從樹根到葉子節點的路徑,必須對樹進行遍歷,本文應該按照:根—>左—>右的方式進行遍歷。
(4)其次,需要考慮的是當我們遍歷到葉子節點時,當路徑值之和不等於給定值時,如何繼續進行下去。
(5)再次,本文采用棧來存儲路徑上的節點,因爲當遍歷到葉子節點時,路徑上節點值之和不等於給定值時只需將該葉子節點移除。首先,對根節點判空,如果爲空返回null,如果只有一個根節點也需要進行特殊判斷;然後,如果根節點不爲空,將根節點壓入棧中(爲了讓整棵樹節點都可能被遍歷到,只要棧中有元素就循環),並用臨時變量count保存存入棧中節點的值,如果棧不爲空就循環,取出棧頂元素,如果該元素有左孩子,就將左孩子壓入棧中,並將值加到count中;如果該元素有右孩子,就將右孩子壓入棧中,並將值加入count中;如果該元素沒有左右孩子,且該元素不是樹根,且count值和給定值相同,則返回true,否則將該元素從棧中移除,並從count中減去對應的值。
(6)在(5)中有一點在此處列出,需要特別注意:我們必須將每次從棧中彈出的節點保存在一個臨時的Set中,並且在將節點的左右孩子存入棧中對其左右孩子是否在Set中進行判定,這樣才能保證每個節點只進入棧一次,否則就會產生死循環。
(7)注:其中棧的peek()方法是取出棧頂元素,而不從棧中移除;棧的pop()方法是取出棧頂元素,並將其從棧中移除;棧的push()方法是將元素壓入棧中;HashSet的contains()方法能夠快速地判斷某一元素是否在該Set中。
(8)這道題注意以上幾個方面就能很容易得到正確答案。這道題其實不難,主要考察對數據結構中棧的使用,另外也對分析問題能力的考察。
(9)希望本文對你有所幫助。謝謝。
算法代碼實現如下:
public static boolean hasPathSum(TreeNode root, int sum) {
if (root == null)
return false;
if (root != null && root.left == null && root.right == null && root.val == sum)
return true;
//每個元素只能進棧一次
Stack<TreeNode> stack = new Stack<TreeNode>();
//保證元素值只進棧一次
Set<TreeNode> set = new HashSet<TreeNode>();
int count = 0;
stack.push(root);
count += root.val;
while (stack.size() != 0) {
TreeNode top = stack.peek();
if (top.left != null && !set.contains(top.left)) {
stack.push(top.left);
count += top.left.val;
} else if (top.right != null && !set.contains(top.right)) {
stack.push(top.right);
count += top.right.val;
} else {
if (top != root && top.left==null && top.right==null && count == sum) {
return true;
} else {
TreeNode pop = stack.pop();
set.add(pop);
count = count - pop.val;
}
}
}
return false;
}