101.平衡二叉树
题目描述[简单]:
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
示例1:
输入:root = [3,9,20,null,null,15,7]
输出:true
思路[递归]:
为了避免重复计算,我们在此处采用的是二叉树的后序遍历。
先检查左子树,获取左子树的高度L;
再检查右子树,获取右子树的高度R;
最后检查L与R的差值是否≤1,若≤1,则满足平衡二叉树的条件。(这里可以用abs()来进行差值运算)
C++代码:
题解1:
/**
* 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:
bool isBalanced(TreeNode* root) {
return getheigh(root) >= 0;
}
int getheigh(TreeNode* root){
if(root == nullptr)//其他表示二叉树的高度
return 0;
int lefth = getheigh(root -> left);//求左子树高度
int righth = getheigh(root -> right);//求右子树高度
if(abs(lefth-righth) <= 1 && lefth >= 0 && righth >=0 ){
return max(lefth,righth) + 1;
}
else{
return -1;//用-1来表示二叉树不平衡的情况
}
}
};
题解2:
class Solution {
public:
bool isBalanced(TreeNode* root) {
return getheigh(root) != -1;
}
int getheigh(TreeNode* root){
if(root == nullptr)//其他表示二叉树的高度
return 0;
int lefth = getheigh(root -> left);//求左子树高度
if(lefth == -1)
return -1;//用-1来表示二叉树不平衡的情况
int righth = getheigh(root -> right);//求右子树高度
if(righth == -1)
return -1;
if(abs(lefth-righth) > 1 )
return -1;
return max(lefth,righth) + 1;
}
};
时间复杂度:O(n);
102.二叉树的层序遍历
题目描述[中等]:
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
思路[BFS遍历使用队列]:
初始让根节点入队
1.获取队列的元素个数,为count(之后左右孩子都要入队,因此我们要用count进行区分)
2.依次弹出队列中的全部节点,访问该节点,确保左右孩子都要入队(遍历count次)
C++代码:
/**
* 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:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if (root == nullptr) ///若根节点为空,直接返回0
return res;
queue<TreeNode*> q; //定义一个队列
q.push(root);//添加根节点
while(!q.empty()) {
//当队列非空
int count = q.size();//获取队列节点数量,即当前节点数
//现在队列中存储的就是当前队列的全部节点,我们现在要将他们全部取出来存到数组里就好了
vector<int> c;//定义存储全部节点的数组
for (int i = 0; i < count; i++) {
TreeNode* node = q.front();
q.pop();
c.push_back(node->val);//把弹出的节点加到数组中
if (node->left) //否则把他们左右孩子加进来
q.push(node->left);
if (node->right)
q.push(node->right);
}
res.push_back(c);//每加完一层,层数都要加1
}
return res;
}
};
时间复杂度:O(n);
111.二叉树的最小深度
题目描述[简单]:
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
示例1:
输入:root = [3,9,20,null,null,15,7]
输出:2
思路[递归]:
找出最小深度其实就是求从根节点到叶子节点的最短路径长度。
本题我们可以用层序遍历、广度优先、长度优先的方法来解答此题。
但是我们可以就单纯只用递归加上三目运算来求解本题。(但是此方法执行时间和内存时间都较大)
C++代码:
思路1【递归+三目运算】:
/**
* 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 minDepth(TreeNode* root) {
if(root == nullptr)
return 0;
int left=minDepth(root->left)
int right=minDepth(root->right);
return (left && right) ? 1+min(left,right) : 1 + left + right;
}
};
在三目运算符下,因为最左侧的条件:(left && right),所以实际1 + left + right执行时该节点最多存在一个子树(1 + left + 0 || 1 + right + 0)或为叶子结点(1 + 0 + 0)。
思路2【DFS】:
class Solution {
public:
int minDepth(TreeNode* root) {
// 判断是不是空树,只有第一次有用,后面递归用不到
if (root ==nullptr)
return 0;
// 说明为叶子节点,深为1
if (root->left == nullptr && root->right == nullptr)
return 1;
// 左空右不空,返回右子树深度且+1
if (root->left == nullptr)
return minDepth(root->right) + 1;
// 右空左不空,返回左子树深度且+1
if (root->right == nullptr)
return minDepth(root->left) + 1;
// 左右都不空,返回左右子树深度较小值且+1
return min(minDepth(root->left), minDepth(root->right)) + 1; // 判断是不是空树,但只在第一次遍历时使用
}
};
思路3【层序遍历】:
class Solution {
public:
int minDepth(TreeNode* root) {
if (root == nullptr) ///若根节点为空,直接返回0
return 0;
queue<TreeNode*> q; //定义一个队列
q.push(root);//添加根节点
int res = 1;//定义一下结果遍历,初始深度为1
// 层数从1开始,到了当前层找到叶子节点,那答案就是当前层数
while(!q.empty()) {
//当队列非空
int count = q.size();//获取队列节点数量,即当前节点数
for (int i = 0; i < count; i++) {
//弹出
TreeNode* node = q.front(); //帮他们把左右孩子加入进来
q.pop();
if (node->left == nullptr && node->right == nullptr) //如果弹出的是叶子节点,就可以直接返回结果
return res;
if (node->left) //否则把他们左右孩子加进来
q.push(node->left);
if (node->right)
q.push(node->right);
}
res++;//每加完一层,层数都要加1
}
return res;
}
};
时间复杂度:O(n);