做題目前隨便說點
-
樹是一種抽象數據類型,一種具有樹結構形式的數據集合。
-
節點個數確定,有層次關係。
-
有根節點。
-
除了根,每個節點有且只有一個父節點。
-
沒有環路。
-
所有數據結構都可以用鏈表表示或者用數組表示,樹也一樣。
257. 二叉樹的所有路徑
給定一個二叉樹,返回所有從根節點到葉子節點的路徑。
說明: 葉子節點是指沒有子節點的節點。
示例:
輸入:
1
/
2 3
5輸出: [“1->2->5”, “1->3”]
解釋: 所有根節點到葉子節點的路徑爲: 1->2->5, 1->3
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/binary-tree-paths
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
解題:
審題:
- 這道理,可以看作是打印葉子節點。順便打印深度遍歷的過程。
- 自上而下的深度遍歷。
- 我們採用先序遍歷
- 那麼從父節點到葉子節點的路徑臨時存放到哪裏呢?
- 我們可以暴力的創建N個臨時遍歷,把這些屬性放到每個節點的擴展屬性中。但是這樣會加大內存開銷。但是一定可行。
- 還有一個思路就是寄存到List中,然後再根據一個子節點,和兩個子節點,和無子節點。但是對字符串的操作頻繁,實際上並沒有節省到必要的內。代碼維護成本也高很多。
- 最終還是建議採用方案一,用節點的擴展屬性。但是內存消耗大。如果採用一個棧存儲性能會好很多。棧的實現可以是數組或者是鏈表。但是在java裏無論是StringBuilder還是Stack都是數組存儲(Stack父類是Vector,同步鎖導致性能不高)
框架代碼如下:
class Solution {
TreeNode rescursive(TreeNode node) {
if( ... ) {
return node
} else {
// 先序遍歷
rescursive(node.left);
rescursive(node.right);
}
}
}
開始解題:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public static List<String> list;
// 相當於備忘錄的棧
public static Stack<Integer> stack = new Stack();
// 打印備忘錄
public static String printStack(int leafNodeVal) {
StringBuilder builder = new StringBuilder();
for(int i : stack) {
builder.append(i + "->");
}
builder.append(leafNodeVal);
return builder.toString();
}
void rescursive(TreeNode node) {
if( node == null ) {
return ;
} else {
// 先序遍歷
boolean isLeaf = (node.left == null && node.right == null);
if(isLeaf) {
// 記錄備忘錄的路徑。由於我們約定不寫葉子節點值到備忘錄,所以不需要退回葉子節點的路徑。
list.add(printStack(node.val));
} else {
// 記一下當前節點
stack.push(node.val);
rescursive(node.left);
rescursive(node.right);
// 遞歸完子節點後後記將自己節點值撤銷。相當於回退路徑。
stack.pop();
}
}
}
public List<String> binaryTreePaths(TreeNode root) {
list = new ArrayList();
rescursive(root);
return list;
}
}
總結:
- 這道題目我們用一個棧來輔助我們,這個棧其實是相當於一個備忘錄,因爲深度遍歷時一個遞推和回溯的過程,免不了在棧裏進進出出的。
- 所以我們在前序遍歷的時候,就進棧,等後序遍歷的時候就退棧,遇到葉子節點就歸檔到list,其他都是細節問題了。然後確保,不要忘記退棧就好。這道題目最難就是推棧。
- 其實這道題目有一個優化的點,就是用stringBuilder來代替stack,不需要又是Stack類,又是StringBuilder類。比較這兩個類的底層實現都是數組。StringBuilder也是可以當作Stack來用的。