代码随想录算法训练营
- 代码随想录算法训练营43期 | Day 15
- 110.平衡二叉树
- 257. 二叉树的所有路径
- 404. 左叶子之和
- 222. 完全二叉树的节点个数
代码随想录算法训练营43期 | Day 15
110.平衡二叉树
/**
* 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 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;
//返回result
int result;
if(abs(rightheight-leftheight)>1)//左右子树高度大于1,不是平衡二叉树
{
return -1;
}else
{
//返回自身节点和左右子树节点的最大值
result = 1 + max(leftheight,rightheight);
}
return result;
}
bool isBalanced(TreeNode* root) {
int result = getheight(root);
if(result==-1)
{
return false;
}else{
return true;
}
}
};
257. 二叉树的所有路径
回溯算法:递归遍历顺序:前序遍历
递归三部曲:
- 确定递归函数的参数
- void travalsal(Treenode* root, vector& path , vector& result)
- 确定函数的终止条件
- 节点遇到叶子节点终止,也就是 if(node->leftnullptr&&node->rightnullptr) return result.push_back(path);
- 单层的递归逻辑
- 这里使用vector 结构path来记录路径,所以要把vector 结构的path转为string格式,再把这个string 放进 result里。
if (cur->left == NULL && cur->right == NULL) { // 遇到叶子节点 string sPath; for (int i = 0; i < path.size() - 1; i++) { // 将path里记录的路径转为string格式 sPath += to_string(path[i]); sPath += "->"; } sPath += to_string(path[path.size() - 1]); // 记录最后一个节点(叶子节点) result.push_back(sPath); // 收集一个路径 return; }
确定单层递归的逻辑:回溯和递归一一对应,一个递归对应一个回溯
if (cur->left) {
traversal(cur->left, path, result);
path.pop_back(); // 回溯
}
if (cur->right) {
traversal(cur->right, path, result);
path.pop_back(); // 回溯
}
class Solution {
public:
// 1. 确定递归函数的参数和返回值
void traversal(TreeNode*node, vector<int>&path, vector<string>&result)
{
//中左右,最后一个节点也要保存在里面
path.push_back(node->val);
//2.确定递归算法的终止条件 遇到叶子结点则返回
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]);
result.push_back(sPath);
return;
}
//3. 单层递归的逻辑关系
//左
if(node->left)
{
traversal(node->left,path,result);
path.pop_back();
}
//右
if(node->right)
{
traversal(node->right,path,result);
path.pop_back();
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<int>path;
vector<string>result;
if(root==nullptr) return result;
traversal(root, path, result);
return result;
}
};
404. 左叶子之和
- 确定递归函数的参数和返回值
- 确定终止条件
- 确定单层递归的逻辑
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
//1. 确定递归的终止条件
if(root==nullptr) return 0;
if(root->left==nullptr&&root->right==nullptr) return 0;
//确定遍历顺序 中序遍历 左 根 右
//确定单层遍历的逻辑顺序 左
int leftval = sumOfLeftLeaves(root->left);
if(root->left!=nullptr&&root->left->left==nullptr&&root->left->right==nullptr)
{
leftval = root->left->val;
}
int rightval = sumOfLeftLeaves(root->right);
int sum = leftval + rightval;
return sum;
}
};
222. 完全二叉树的节点个数
利用完全二叉树的特性进行计算节点个数
完全二叉树:
除了底层节点,上层的节点数量都是满的,且底层的节点是从左到右依次排序;
普通二叉树解法:
class Solution {
public:
int getNodeNum(TreeNode* node)
{
//终止条件
if(node==nullptr) return 0;
//后序遍历
int leftnum = getNodeNum(node->left);
int rightnum = getNodeNum(node->right);
int result = leftnum + rightnum + 1;
return result;
}
int countNodes(TreeNode* root) {
int result = getNodeNum(root);
return result;
}
};
完全二叉树解法:
class Solution {
public:
//完全二叉树特性解法 、
int getNums(TreeNode* node)
{
//确定递归的终止条件 节点为空,返回0
if(node==nullptr) return 0;
//确定是完全儿二叉树
TreeNode* left = node->left;
TreeNode* right = node->right;
//深度
int leftdepth = 0;
int rightdepth = 0;
//左子树 左子树不为空,循环往左,左子树深度++
while(left)
{
left = left->left;
leftdepth++;
}
//右子树
while(right)
{
right = right->right;
rightdepth++;
}
//判断是否是完全二叉树
if(rightdepth==leftdepth)
{
return (2<<leftdepth)-1;
}
//计算左
int leftnum = getNums(node->left);
//计算右
int rightnum = getNums(node->right);
return leftnum + rightnum + 1;
}
int countNodes(TreeNode* root) {
return getNums(root);
}
};