算法-二叉樹DFS-從先序遍歷還原二叉樹
1 搜索插入位置
1.1 題目出處
https://leetcode-cn.com/problems/recover-a-tree-from-preorder-traversal/
1.2 題目描述
我們從二叉樹的根節點 root 開始進行深度優先搜索。
在遍歷中的每個節點處,我們輸出 D 條短劃線(其中 D 是該節點的深度),然後輸出該節點的值。(如果節點的深度爲 D,則其直接子節點的深度爲 D + 1。根節點的深度爲 0)。
如果節點只有一個子節點,那麼保證該子節點爲左子節點。
給出遍歷輸出 S,還原樹並返回其根節點 root。
示例 1:
輸入:“1-2–3--4-5–6--7”
輸出:[1,2,5,3,4,6,7]
示例 2:
輸入:“1-2–3—4-5–6—7”
輸出:[1,2,5,3,null,6,null,4,null,7]
示例 3:
輸入:“1-401–349—90–88”
輸出:[1,401,null,349,88,90]
提示:
原始樹中的節點數介於 1 和 1000 之間。
每個節點的值介於 1 和 10 ^ 9 之間。
2 DFS
2.1 思路
給定字符串是以前序遍歷生成,那我們就對應用DFS順序來遍歷字符串來生成樹就好了。
每趟DFS結束條件是當前層深度已經不大於下一待處理節點深度,說明需要返回給上一層父節點處理。
2.2 代碼
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
// 當前遍歷的原字符串位置
private int position = 0;
// 下一個尚未處理節點的深度
private int nextD = 0;
public TreeNode recoverFromPreorder(String S) {
return dfs(0, S.toCharArray());
}
// 思想:需要獲取下一節點的深度,和當前深度對比決定是否能作爲子節點
public TreeNode dfs(int curD, char[] chars){
if(position == chars.length){
return null;
}
int curV = 0;
// 獲取當前節點數值
while(position < chars.length && chars[position] != '-'){
curV = curV * 10 + (chars[position++] - '0');
}
// 構建當前節點
TreeNode curT = new TreeNode(curV);
// 注意這裏要重新計算nextD,因爲當前節點就是上一節點的下一處理節點
nextD = 0;
// 獲取當前下一節點層數
while(position < chars.length && chars[position] == '-'){
position++;
nextD++;
}
if(nextD > curD){
// 僅當下一節點層數大於當前節點,纔將下一節點設爲當前節點左子樹
curT.left = dfs(nextD, chars);
}
// 這裏千萬注意,不能放在一個if裏面
// 因爲nextD可能在上一個dfs裏面已經變化!
if(nextD > curD){
// 到這裏,左子樹已經dfs完成,所以當前下一節點自然是本節點右子樹
curT.right = dfs(nextD, chars);
}
return curT;
}
}
2.3 時間複雜度
O(N)
2.4 空間複雜度
O(N)