110. 平衡二叉樹
題目連結:https://leetcode.cn/problems/balanced-binary-tree/
題目難度:簡單
文章講解:https://programmercarl.com/0110.平衡二叉樹.html
影片講解:https://www.bilibili.com/video/BV1Ug411S7my
題目狀態:透過
思路:
採用遞迴的方式,遍歷每個節點的左右孩子的深度以及其之間的深度差是否超過 1,如果超過 1 的話,就直接返回false
,直到遍歷結束。
程式碼實現:
/**
* 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 isBalancedUtil(TreeNode *root, int &balanced) {
if(root == nullptr) return 0;
int leftHeight = isBalancedUtil(root->left, balanced);
if(balanced == 0) return 0;
int rightHeight = isBalancedUtil(root->right, balanced);
if(balanced == 0) return 0;
if(abs(leftHeight - rightHeight) > 1) balanced = 0;
return max(leftHeight, rightHeight) + 1;
}
bool isBalanced(TreeNode* root) {
int balanced = 1;
isBalancedUtil(root, balanced);
return balanced;
}
};
程式碼隨想錄提供了一種更好的程式碼:
class Solution {
public:
int getHeight(TreeNode *node) {
if(node == nullptr) return 0;
int leftHeight = getHeight(node->left);
if(leftHeight == -1) return -1;
int rightHeight = getHeight(node->right);
if(rightHeight == -1) return -1;
return abs(leftHeight - rightHeight) > 1 ? -1 : (max(leftHeight, rightHeight) + 1);
}
bool isBalanced(TreeNode *root) {
return getHeight(root) == -1 ? false : true;
}
};
257. 二叉樹的所有路徑
題目連結:https://leetcode.cn/problems/binary-tree-paths/
題目難度:簡單
文章講解:https://programmercarl.com/0257.二叉樹的所有路徑.html
影片講解:https://www.bilibili.com/video/BV1ZG411G7Dh
題目狀態:一點思路也沒有
學習思路:
學習回溯,看下圖
回溯和遞迴是不分開的,當每次進行遞迴的時候將之前儲存的路徑中的節點pop
出去,這就是回溯。
定義遞迴函式:
- 傳入引數:
a.TreeNode *node
:傳入一個節點。
b.vector<int> path
:透過一個path
來記錄沿途的路徑,便於之後的回溯。
c.vector<string> res
:用來記錄最終結果。 - 返回值:沒有返回值,遞迴的結果在
res
中存放。 - 終止條件:當該節點的左孩子和右孩子都為
nullptr
時,遞迴終止。 - 遞迴思路:採用前序遍歷,先將節點壓入
path
中,再判斷其左右孩子是否都為nullptr
(此時為遞迴結束,即該節點為葉子節點),若不為nullptr
,分別將其左右孩子(不為空的那個)進入遞迴,此時將path
中該節點pop
出來(這個就是回溯)。
程式碼實現:
/**
* 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:
void backtracking(TreeNode *node, vector<int> &path, vector<string> &res) {
// 中
path.push_back(node->val);
// 終止條件
if(node->left == nullptr && node->right == nullptr) {
string sPath;
for(int i = 0; i < path.size() - 1; ++i) {
sPath += to_string(path[i]);
sPath += "->";
}
sPath += to_string(path[path.size() - 1]);
res.push_back(sPath);
return;
}
// 左
if(node->left) {
backtracking(node->left, path, res);
path.pop_back();
}
// 右
if(node->right) {
backtracking(node->right, path, res);
path.pop_back();
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> res;
vector<int> path;
if(root == nullptr) return res;
backtracking(root, path, res);
return res;
}
};
404. 左葉子之和
題目連結:https://leetcode.cn/problems/sum-of-left-leaves/
題目難度:簡單
文章講解:https://programmercarl.com/0404.左葉子之和.html
影片講解:https://www.bilibili.com/video/BV1GY4y1K7z8
題目狀態:透過
個人思路:
定義一個int
型別變數leftSum
,用來儲存結果使用層序遍歷,當遍歷到該節點的左孩子時,若其左孩子沒有左孩子和右孩子(即該節點的左孩子為葉子節點),將其值加入leftSum
中。
程式碼實現:
/**
* 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 sumOfLeftLeaves(TreeNode* root) {
queue<TreeNode *> que;
if(root == nullptr) return 0;
int leftSum = 0;
que.push(root);
while(!que.empty()) {
TreeNode *node = que.front();
que.pop();
if(node->left) {
que.push(node->left);
if(node->left->left == nullptr && node->left->right == nullptr) leftSum += node->left->val;
}
if(node->right) que.push(node->right);
}
return leftSum;
}
};
遞迴思想的程式碼:
/**
* 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 sumOfLeftLeaves(TreeNode* root) {
if(root == nullptr) return 0;
if(root->left == nullptr && root->right == nullptr) return 0;
int leftValue = sumOfLeftLeaves(root->left);
if(root->left && !root->left->left && !root->left->right) leftValue += root->left->val;
int rightValue = sumOfLeftLeaves(root->right);
// 這裡面leftValue代表左孩子的左葉子節點值之和,rightValue代表右孩子的左葉子節點值之和
int sum = leftValue + rightValue;
return sum;
}
};
222. 完全二叉樹的節點個數
題目連結:https://leetcode.cn/problems/count-complete-tree-nodes/
題目難度:簡單
文章講解:https://programmercarl.com/0222.完全二叉樹的節點個數.html
影片講解:https://www.bilibili.com/video/BV1eW4y1B7pD
題目狀態:透過
思路:
層序遍歷,加個計數sum
。
程式碼實現:
/**
* 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 countNodes(TreeNode* root) {
queue<TreeNode *> que;
if(root == nullptr) return 0;
que.push(root);
int sum = 1;
while(!que.empty()) {
TreeNode *node = que.front();
que.pop();
if(node->left) {
que.push(node->left);
sum++;
}
if(node->right) {
que.push(node->right);
sum++;
}
}
return sum;
}
};
遞迴方法:(利用完全二叉樹的特性,2的深度次方-1,這樣只需要遍歷完全二叉樹的左孩子和右孩子最邊上的節點即可)
class Solution {
public:
int countNodes(TreeNode* root) {
if (root == nullptr) return 0;
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftDepth = 0, rightDepth = 0; // 這裡初始為0是有目的的,為了下面求指數方便
while (left) { // 求左子樹深度
left = left->left;
leftDepth++;
}
while (right) { // 求右子樹深度
right = right->right;
rightDepth++;
}
if (leftDepth == rightDepth) {
return (2 << leftDepth) - 1; // 注意(2<<1) 相當於2^2,所以leftDepth初始為0
}
return countNodes(root->left) + countNodes(root->right) + 1;
}
};