- 相同节点值的最大路径长度 687. Longest Univalue Path(Medium)
- 间隔遍历 337. House Robber III(Medium)
- 找出二叉树中第二小的节点 671. Second Minimum Node In a Binary Tree(Easy)
- 一棵树每层节点的平均数 637. Average of Levels in Binary Tree(Easy)
- 得到左下角的节点 513. Find Bottom Left Tree Value(Easy)
递归
相同节点值的最大路径长度
class Solution {
public:
int result;
int sameValueMaxDepth(TreeNode* root){
if(root == NULL)
return 0;
int L = sameValueMaxDepth(root->left);
int R = sameValueMaxDepth(root->right);
if(root->left != NULL && root->left->val == root->val)
L = 1 + L;
else
L = 0;
if(root->right != NULL && root->right->val == root->val)
R = 1 + R;
else
R = 0;
result = max(result, L+R);
return max(L, R);
}
int longestUnivaluePath(TreeNode* root) {
/*
思路:对于任意一个节点,只要知道了从左右子树出发节点值相同的路径的最大深度就能够求到该根节点对应的最长的单值路径
时间复杂度:O(n)
空间复杂度:O(n)
*/
if(root == NULL)
return 0;
result = 0;
sameValueMaxDepth(root);
return result;
}
};
间隔遍历
参考:https://leetcode.com/problems/house-robber-iii/discuss/79333/Simple-C%2B%2B-solution
利用引用简化问题,如果一个函数要多个返回值可考虑参数中传入引用,在函数中修改参数值,虽然可读性降低但可以降低代码复杂程度。
class Solution {
public:
int robHelper(TreeNode* node, int &L, int& R){
if(node == NULL)
return 0;
int LL = 0, LR = 0, RL = 0, RR = 0;
L = robHelper(node->left, LL, LR);
R = robHelper(node->right, RL, RR);
return max(node->val + LL + LR + RL + RR, L + R);
}
int rob(TreeNode* root) {
/*
思路:在进行抢劫时抢了根节点就不能再考虑左右子节点,所以需要多考虑一层,抢了根节点下一步就只能抢左右子树的子树,不抢根节点就可以强左右子树
时间复杂度:O(n)
空间复杂度:O(n)
*/
int L = 0, R = 0;
return robHelper(root, L, R);
}
};
找出二叉树中第二小的节点
使用递归的方法解决问题时不一定要使用原始方法,例如本题,不一定要递归调用findSecondMinimumValue函数,可以构造一个minValue函数,返回大于rootVal的最小的值。
class Solution {
public:
int minValue(TreeNode* node, int rootVal){
if(node == NULL)
return -1;
if(node->val > rootVal)
return node->val;
int lmin = minValue(node->left, rootVal);
int rmin = minValue(node->right, rootVal);
if(lmin == -1) return rmin;
if(rmin == -1) return lmin;
return min(lmin, rmin);
}
int findSecondMinimumValue(TreeNode* root) {
/*
思路:minValue返回大于根节点的值中最小的值
时间复杂度:O(n)
空间复杂度:O(n)
*/
if(root == NULL)
return -1;
return minValue(root, root->val);
}
};
层次遍历
一棵树每层节点的平均数
class Solution {
public:
vector<double> averageOfLevels_twovec(TreeNode* root) {
/*
思路:用两个vector循环使用存节点
时间复杂度:O(n)
空间复杂度:O(n)
*/
vector<double> ans;
vector<TreeNode*> layer1, layer2;
layer1.push_back(root);
while(!layer1.empty()){
double sum = 0;
layer2.clear();
for(int i = 0;i < layer1.size(); i++){
TreeNode* node = layer1[i];
if(node->left != NULL)
layer2.push_back(node->left);
if(node->right != NULL)
layer2.push_back(node->right);
sum += node->val;
}
ans.push_back(sum / (double)(layer1.size()));
layer1.assign(layer2.begin(), layer2.end());
}
return ans;
}
vector<double> averageOfLevels(TreeNode* root) {
/*
思路:用一个queue每一层先记录节点个数,然后遍历计算均值并存入子节点
时间复杂度:O(n)
空间复杂度:O(n)
*/
vector<double> ans;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
int cnt = q.size();
double sum = 0;
for(int i = 0;i < cnt; i++){
TreeNode* node = q.front();
q.pop();
if(node->left != NULL) q.push(node->left);
if(node->right != NULL) q.push(node->right);
sum += node->val;
}
ans.push_back(sum / cnt);
}
return ans;
}
};
得到左下角的节点
层次遍历惯例,先记录队列中节点个数,也就是当前层的节点个数,再遍历,遍历过程中将子节点加入到队列中
class Solution {
public:
int findBottomLeftValue(TreeNode* root) {
/*
思路:层次遍历,遍历每一层时将第一个节点的值作为答案
时间复杂度:O(n)
空间复杂度:O(n)
*/
queue<TreeNode*> q;
q.push(root);
int ans;
while(!q.empty()){
int num = q.size();
for(int i = 0;i < num; i++){
TreeNode* node = q.front();
q.pop();
if(i == 0)
ans = node->val;
if(node->left != NULL) q.push(node->left);
if(node->right != NULL) q.push(node->right);
}
}
return ans;
}
};