題目敘述

  • 題目難度: Easy
  • 題目敘述: 給定一個 Binary Tree 的root,反轉他以後,回傳它的 root

解法

一開始的想法

題目敘述很簡短,但基本上就是除了root以外,左葉子樹的成員都對調

但學會了上一題遞迴的概念後,這題幾乎是秒解,但還是有考慮不周到的地方

我一開始的想法,就是一樣透過遞迴的方式,一開始就 traverse 到樹葉,碰到樹葉後,再將他們的左右child進行對調,之後一路fuction return 回去,然後回傳一開始原先的root即可

我一開始的思路會是下面這樣

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
TreeNode *BT::invertTree(TreeNode* root){
TreeNode *tmp = 0;
TreeNode *current = root;
if (root == nullptr) {
return nullptr;
}
if(current->left != NULL && current->right != NULL){
invertTree(current->left);
invertTree(current->right);
}

tmp = current->left;
current->left = current->right;
current->right = tmp;
tmp =0;

return root;
}

但上面的 if(current->left != NULL && current->right != NULL){} 會在 skewd tree 的時候出問題:

原本給的 tree會是 [2,3,null,1],如果按照這樣跑出來會是 [2,null,3,1]

題目原先的樹會長這樣:

預期輸出: [2,null,3,null,1]

但我上面的作法會變成: [2,null,3,1],這是因為條件判斷 if(current->left != NULL && current->right != NULL) 只在當前節點的左右子節點都不為 NULL 的情況下進行遞迴調用和交換。因此,它無法處理只有一個子節點的情況,從而導致錯誤的樹結構

我的解法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
TreeNode *tmp = 0;
TreeNode *current = root;
if (root == nullptr) {
return nullptr;
}

invertTree(current->left);
invertTree(current->right);


tmp = current->left;
current->left = current->right;
current->right = tmp;
tmp =0;

return root;
}
};

說明

上面使用深度優先搜索(DFS)的遞迴方法遍歷整棵樹。在遞迴過程中,首先翻轉每個節點的左右子樹,然後進行交換操作。這樣,每次遞迴完成後,當前節點的子樹就被翻轉了。最終,整棵樹的所有節點都被翻轉。

翻轉後,樹中每個節點的左子節點和右子節點都被交換,形成了整棵樹的鏡像。

執行結果

完整本地測試程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# include <iostream>
# include <queue>

using namespace std;

class BT;
class TreeNode{
public:
int val;
TreeNode *left, *right;

TreeNode():val(0),left(0),right(0){};
TreeNode(int x):val(x),left(0),right(0){};
TreeNode(int x, TreeNode* leftnode, TreeNode* rightnode):val(x),left(leftnode),right(rightnode){};
friend class BT;
};


class BT{
public:
TreeNode *root = new TreeNode;

//constructor
BT(): root(0) {};
BT(TreeNode* node):root(node){};

//member function
TreeNode * invertTree(TreeNode* root);
void levelOrder();
};



void BT::levelOrder(){
queue<TreeNode*> q;
q.push(this->root);

while(!q.empty()){
TreeNode *current = q.front();
q.pop();

cout << current->val << " ";
if(current->left != NULL){
q.push(current->left);
}
if(current->right != NULL){
q.push(current->right);
}
}
}

TreeNode *BT::invertTree(TreeNode* root){
TreeNode *tmp = 0;
TreeNode *current = root;
if (root == nullptr) {
return nullptr;
}
invertTree(current->left);
invertTree(current->right);


tmp = current->left;
current->left = current->right;
current->right = tmp;
tmp =0;

return root;
}

int main(){


TreeNode *nodeA = new TreeNode(4);
TreeNode *nodeB = new TreeNode(2);
TreeNode *nodeC = new TreeNode(7);
TreeNode *nodeD = new TreeNode(1);
TreeNode *nodeE = new TreeNode(3);
TreeNode *nodeF = new TreeNode(6);
TreeNode *nodeG = new TreeNode(9);

// TreeNode *nodeA = new TreeNode(2);
// TreeNode *nodeB = new TreeNode(3);
// TreeNode *nodeC = new TreeNode(1);


nodeA->left = nodeB;
nodeA->right = nodeC;
nodeB->left = nodeD;
nodeB->right = nodeE;
nodeC->left = nodeF;
nodeC->right = nodeG;

// nodeA->right = nodeB;
// nodeB->right = nodeC;
// nodeB->left = NULL;


BT T(nodeA);

cout << "Level Order: " << endl;
T.levelOrder();

T.invertTree(T.root);
cout << "\nAfter Inverstion:" << endl;
T.levelOrder();

return 0;
}

複雜度

時間複雜度

$O(N)$, 每個節點都會被訪問一次,其中 n 是樹中節點的數量。

空間複雜度

在一般情況下,對於一棵平衡二元樹,空間複雜度是 $O(log n)$,因為樹的高度 h 大約為 $log n$。但對於完全不平衡的樹,空間複雜度會退化到 $O(n)$