110. 平衡二叉树
第一想法:首先要明确平衡二叉树的定义?左右节点的高度差不超过1?不会概念感觉无法下手...
返回参数返回int,为了标记已经不是平衡二叉树,用-1作标记
int traversal(TreeNode* root){
if(root==nullptr) return 0;
//递归左孩子和右孩子
int leftdepth = traversal(root->left);
int rightdepth = traversal(root->right);
//如果左右孩子有-1,直接返回-1
if (leftdepth==-1) return -1;
if(rightdepth==-1) return -1;
int result = abs(leftdepth-rightdepth) > 1? -1:max(leftdepth, rightdepth)+1;
//判断左右孩子是否为-1
return result;
}
bool isBalanced(TreeNode* root) {
if(root==nullptr) return true;
int result = traversal(root);
if(result == -1) return false;
else return true;
}
看完想法:概念差不多正确,完整的高度平衡的二叉树定义是:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1,迭代记录节点当前的高度,如果不是平衡二叉树的话,就记为-1
257. 二叉树的所有路径
第一想法:和普通递归一样,在push_back根节点以及左右孩子的If都不执行的时候,开始把string转化为result
看完想法:一般的递归是 root==nullptr 的时候处理递归逻辑,但是与题目不符,我们需要遇到叶子节点的时候就放入result。并且遍历的时候用path遍历,类型是vector<int>, str作为result的元素,是一个暂存元素的中间变量。其中,把其他元素转变为string可以用to_string( )库函数。在执行递归回溯时,str的弹出(vector)可以用pop_back();
终止逻辑如下:
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;
}
完整版
void traversal(TreeNode* root, vector<int>& str, vector<string>& result){
//中,提前放入str
str.push_back(root->val);
if(root->left == nullptr && root->right == nullptr) {
//终止条件
string path;
for(int i = 0; i<str.size()-1; i++){
path += to_string(str[i]);
path += "->";
}
path += to_string(str[str.size()-1]);
result.push_back(path);
}
//递归规则
if(root->left) {
traversal(root->left, str, result);
str.pop_back();
}
if(root->right) {
traversal(root->right, str, result);
str.pop_back();
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
vector<int> str;
if(root==nullptr) return result;
traversal(root, str, result);
return result;
404.左叶子之和
第一想法:重点判断是不是左叶子,需要通过父节点来判断是不是左叶子。具体来说,当前遍历节点的左节点没有孩子并右节点有孩子,就是左叶子
看完想法:忽略了一点,最后需要求左子树的左叶子之和和右子树的左叶子之和才行,因此递归函数返回值应该是Int,,判断是不是叶子节点需要放在递归逻辑模块里
222. 完全二叉树的节点个数
第一想法:用最大深度的解法去解完全ok,但是达不到理想的时间复杂度。不知道咋利用完全二叉树的个性
看完想法:完全二叉树:除了底层节点没满,其余节点都满了,并且底层节点都集中在树的左侧,节点不连续排列不是完全二叉树!
完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。
对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。
对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。怎么判断是否为满二叉树,看左侧深度和右侧深度是否相同,同就是满二叉树;并且没有遍历中间节点,在二叉树很大的时候节约了很多时间成本.
在写终止条件时,要判断是否先等,不同则继续迭代;写递归逻辑时仍然要返回result
int result = 0;
int traversal(TreeNode* root){
if(root==nullptr) return 0;
int leftdepth=0;
int rightdepth=0;
//记录左右侧深度,从0开始
TreeNode* left = root->left;
TreeNode* right = root->right;
while(left){
left = left->left;
leftdepth++;
}
while(right){
right = right->right;
rightdepth++;
}
if(leftdepth==rightdepth){
return (2<<leftdepth)-1;
}
//遍历逻辑
int leftnode = traversal(root->left);
int rightnode = traversal(root->right);
result = leftnode + rightnode +1;
return result;
}
int countNodes(TreeNode* root) {
if(root==nullptr) return 0;
result = traversal(root);
return result;
}