請完成一個函式,輸入一個二叉樹,該函式輸出它的映象。
例如輸入:
4
/
2 7
/ \ /
1 3 6 9
映象輸出:
4
/
7 2
/ \ /
9 6 3 1
示例 1:
輸入:root = [4,2,7,1,3,6,9]
輸出:[4,7,2,9,6,3,1]
二叉樹像定義:對於二叉樹中任意節點 root,設其左/右子節點分別為 left,right;則在二叉樹的映象中的對應 root 節點,其左/右節點分別為 right,left。
方法一:遞迴法
- 根據二叉樹映象的定義,考慮遞迴遍歷(dfs)二叉樹,交換每個節點的左/右子節點,即可生成二叉樹的映象。
遞迴解析:
終止條件:當節點 root 為空時(即越過葉節點),則返回 null;
遞推工作:
- 初始化節點 tmp,用於暫存 root 的左子節點;
- 開啟遞迴 右子節點 mirrorTree(root.right),並將返回值作為 root 的 左子節點。
- 開啟遞迴 左子節點 mirrorTree(tmp),並將返回值作為 root 的 右子節點。
返回值:返回當前節點 root;
Q:為何需要暫存 root 的左子節點?
A:在遞迴右子節點root.left = mirrorTree(root.right);
執行完畢後,root.left 的值已經發生改變,此時遞迴左子節點 mirrorTree(root.left) 則會出問題。
程式碼
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root == null) return null;
TreeNode tmp = root.left;
root.left = mirrorTree(root.right);
root.right = mirrorTree(tmp);
return root;
}
}
複雜度分析
- 時間複雜度 O(N) :其中 N 為二叉樹的節點數量,建立二叉樹映象需要遍歷所有節點,佔用 O(N) 的時間。
- 空間複雜度 O(N) :最差情況下(當二叉樹退化成連結串列),遞迴時系統需要 O(N) 大小的棧空間。
題解來源
作者:jyd
連結:leetcode-cn.com/problems/er-cha-sh...
來源:力扣(LeetCode)
方法二:輔助棧(或佇列)
- 利用棧或佇列遍歷樹的所有節點 node,並交換每個 node 的左/右子節點。
演算法流程:
特例處理:當 root 為空時,直接返回 null。
初始化:棧(或佇列),本文用棧,並加入根節點 root。
迴圈交換:當棧 stack 為空時跳出:
- 出棧:記為 node;
- 新增左/右子節點:將 node 的左/右子節點入棧;
- 交換:交換 node 的左/右子節點。
返回值:返回根節點 root。
程式碼
class Solution {
public TreeNode mirrorTree(TreeNode root) {
if(root == null) return null;
Stack<TreeNode> stack = new Stack<>() {{ add(root); }};
while(!stack.isEmpty()) {
TreeNode node = stack.pop();
if(node.left != null) stack.add(node.left);
if(node.right != null) stack.add(node.right);
TreeNode tmp = node.left;
node.left = node.right;
node.right = tmp;
}
return root;
}
}
複雜度分析
- 時間複雜度 O(N) :其中 N 為二叉樹節點的數量,建立二叉映象樹需要遍歷樹的所有節點,佔用 O(N) 的時間。
- 空間複雜度 O(N) :最差情況下,當為滿二叉樹,棧 stack 最多同時儲存 N/2 個節點,佔用 O(N) 的額外空間。
題解來源
作者:jyd
連結:leetcode-cn.com/problems/er-cha-sh...
來源:力扣(LeetCode)
來源:力扣(LeetCode)
連結:leetcode-cn.com/problems/er-cha-sh...
本作品採用《CC 協議》,轉載必須註明作者和本文連結