解法一 Recursive (String or StringBuilder)
思路
使用 preorder traversal, 我們可以通過 String 的疊加或者 StringBuilder 的 append(), 對路徑進行遍歷。
我們需要定義一個 ArrayList 返回所有路徑;使用 StringBuilder 使需要新建 SB 物件。
定義一個遍歷樹的方法 searchTree:
如果這個節點本身為 null, 那麼就退出遍歷;如果某個節點左右子都為 null, 就將所記錄的字串新增進 ArrayList 中;否則,對這個節點的左右子樹進行 searchTree() 的遞迴呼叫。
程式碼
// 使用 String 疊加
Class Solution () {
public List<String> binaryTreePaths(TreeNode root) {
ArrayList<String> paths = new ArrayList<>();
searchTree(root, "", paths);
return paths;
}
public void searchTree (TreeNode root, String str, ArrayList<String> paths) {
if (root == null) {
return;
}
// 至少說明 root 在路徑中因為非 null
if (root.left == null && root.right == null) {
paths.add(str + root.val);
}
// 其他情況,說明 root 在路徑中, str 要新增 root.val,再搜尋左右子樹是否有路徑
searchTree(root.left, str + root.val + "->", paths);
searchTree(root.right, str + root.val + "->", paths);
}
}
// 使用 StringBuilder
Class Solution () {
public List<String> binaryTreePaths(TreeNode root) {
ArrayList<String> paths = new ArrayList<>();
StringBuilder sb = new StringBuilder();
searchTree(root, sb, paths);
return paths;
}
public void searchTree (TreeNode root, StringBuilder sb, ArrayList<String> paths) {
if (root == null) {
return;
}
// 至少說明 root 在路徑中因為非 null
int len = sb.length();
sb.append(root.val);
if (root.left == null && root.right == null) {
paths.add(sb.toString());
}
// 其他情況,說明 root 在路徑中
sb.append("->");
searchTree(root.left, sb, paths);
searchTree(root.right, sb, paths);
sb.setLength(len); // back track to before root
}
}
複雜度分析
- 時間複雜度
- 最好情況
- 最壞情況
- 平均情況
- 空間複雜度
解法二 Iteration
思路
程式碼
複雜度分析
- 時間複雜度
- 最好情況
- 最壞情況
- 平均情況
- 空間複雜度