題目1 226. 翻轉二叉樹
給你一棵二叉樹的根節點 root
,翻轉這棵二叉樹,並返回其根節點。
示例 1:
輸入:root = [4,2,7,1,3,6,9]
輸出:[4,7,2,9,6,3,1]
示例 2:
輸入:root = [2,1,3]
輸出:[2,3,1]
示例 3:
輸入:root = []
輸出:[]
提示:
- 樹中節點數目範圍在
[0, 100]
內 -100 <= Node.val <= 100
思路
這道題可以用先序,中序,後序或者層序遍歷去做,思路都是類似的。
遞迴呼叫
注意遞迴結束條件是root為nullptr,在每個非空結點上進行左右孩子指標的交換就行了。
程式碼
/**
* 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) {
if(root == nullptr) return root;
TreeNode* tmp = root->left;
root->left = root->right;
root->right = tmp;
invertTree(root->left);
invertTree(root->right);
return root;
}
};
迭代遍歷翻轉
使用一個輔助的棧或者佇列來儲存子結點就可以做了。
程式碼
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
stack<TreeNode*> nodeStack;
nodeStack.push(root);
while(!nodeStack.empty())
{
TreeNode* curNode = nodeStack.top();
nodeStack.pop();
if(curNode == nullptr)
continue;
nodeStack.push(curNode->left);
nodeStack.push(curNode->right);
swap(curNode->left, curNode->right);
}
return root;
}
};
題目2 101. 對稱二叉樹
給你一個二叉樹的根節點 root
, 檢查它是否軸對稱。
示例 1:
輸入:root = [1,2,2,3,4,4,3]
輸出:true
示例 2:
輸入:root = [1,2,2,null,3,null,3]
輸出:false
提示:
- 樹中節點數目在範圍
[1, 1000]
內 -100 <= Node.val <= 100
思路
這道題就是將樹拆分為左右兩個子樹,對子樹進行相反方向的遍歷比較就行了,可以使用遞迴法和迭代法,思路是類似的我用的是迭代法。
迭代法
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(!root->left && !root->right)
return true;
stack<TreeNode*> nodeStack1, nodeStack2;
nodeStack1.push(root->left);
nodeStack2.push(root->right);
while(!nodeStack1.empty() && !nodeStack2.empty())
{
TreeNode* lft = nodeStack1.top(),
* rht = nodeStack2.top();
nodeStack1.pop();
nodeStack2.pop();
if(!lft && !rht)
{
continue;
}
if(!lft || !rht || lft->val != rht->val)
return false;
#define PUSH(STACK, NODE, POSITION) \
STACK.push(NODE->POSITION);
PUSH(nodeStack1, lft, left);
PUSH(nodeStack1, lft, right);
PUSH(nodeStack2, rht, right);
PUSH(nodeStack2, rht, left);
#undef PUSH
}
return nodeStack1.empty() && nodeStack2.empty();
}
題目3 104. 二叉樹的最大深度
給定一個二叉樹 root
,返回其最大深度。
二叉樹的 最大深度 是指從根節點到最遠葉子節點的最長路徑上的節點數。
示例 1:
輸入:root = [3,9,20,null,null,15,7]
輸出:3
示例 2:
輸入:root = [1,null,2]
輸出:2
提示:
- 樹中節點的數量在
[0, 104]
區間內。 -100 <= Node.val <= 100
思路
這道題可以用遞迴法(前,後序遍歷)或者迭代法(層序遍歷)來計算出深度,基礎題。
遞迴法
/**
* 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:
int Nextdepth(TreeNode* root)
{
if(!root)
{
return 0;
}
return 1 + max(Nextdepth(root->left), Nextdepth(root->right));
}
int maxDepth(TreeNode* root) {
return Nextdepth(root);
}
};
迭代法
class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root)
return 0;
queue<TreeNode*> nodeQueue;
nodeQueue.push(root);
int depth = 0;
while(!nodeQueue.empty())
{
int num = nodeQueue.size();
for(int i = 0; i < num; i++)
{
TreeNode* node = nodeQueue.front();
nodeQueue.pop();
if(node->left)
nodeQueue.push(node->left);
if(node->right)
nodeQueue.push(node->right);
}
depth++;
}
return depth;
}
};
題目4 111. 二叉樹的最小深度
給定一個二叉樹,找出其最小深度。
最小深度是從根節點到最近葉子節點的最短路徑上的節點數量。
說明:葉子節點是指沒有子節點的節點。
示例 1:
輸入:root = [3,9,20,null,null,15,7]
輸出:2
示例 2:
輸入:root = [2,null,3,null,4,null,5,null,6]
輸出:5
提示:
- 樹中節點數的範圍在
[0, 105]
內 -1000 <= Node.val <= 1000
思路
和最大深度類似考察基本功,用遞迴法遍歷每一個結點獲取最小深度之後累加得到結果;或者用層序遍歷迭代到最淺的無雙child節點終止。
遞迴法
class Solution {
public:
int NextDepth(TreeNode* root)
{
if(!root)
return 0;
if(!root->left && root->right)
return 1 + NextDepth(root->right);
if(root->left && !root->right)
return 1 + NextDepth(root->left);
return 1 + min(NextDepth(root->left), NextDepth(root->right));
}
int minDepth(TreeNode* root) {
if(!root)
return 0;
return NextDepth(root);
}
};
迭代法
class Solution {
public:
int minDepth(TreeNode* root) {
if(!root)
return 0;
queue<TreeNode*> nodeQueue;
nodeQueue.push(root);
int result = 0;
while(!nodeQueue.empty())
{
int num = nodeQueue.size();
for(int i = 0; i < num; i++)
{
TreeNode* curNode = nodeQueue.front();
nodeQueue.pop();
//若節點無左右child,則為最淺的節點,返回最小深度
if(!curNode->left && !curNode->right)
{
return result + 1;
}
if(curNode->left)
nodeQueue.push(curNode->left);
if(curNode->right)
nodeQueue.push(curNode->right);
}
result++;
}
return result;
}
};