版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/musechipin/article/details/86472101
【背诵】二叉树的递归和非递归遍历方法
97. 二叉树的最大深度
maxDepth返回以当前root为根节点的树的最大深度,出口为叶子的下一层节点深度为0。
class Solution {
public:
int maxDepth(TreeNode * root) {
if (root==NULL) return 0;
int left=maxDepth(root->left);
int right=maxDepth(root->right);
return max(left,right)+1;
}
};
480. 二叉树的所有路径
函数返回以当前root为根的所有路径组成的vector,出口:1.空节点返回空向量,2.叶子节点只返回节点值形成的字符串而不加->
class Solution {
public:
vector<string> binaryTreePaths(TreeNode * root) {
vector<string> res;
if (root==NULL) return res;
if (root->left==NULL && root->right==NULL) {res.push_back(to_string(root->val)); return res;}
vector<string> left=binaryTreePaths(root->left);
vector<string> right=binaryTreePaths(root->right);
for (int i=0;i<left.size();i++) {
string tmp=to_string(root->val)+"->"+left[i];
res.push_back(tmp);
}
for (int i=0;i<right.size();i++) {
string tmp=to_string(root->val)+"->"+right[i];
res.push_back(tmp);
}
return res;
}
};
596. 最小子树
方法一,使用全局变量:
class Solution {
public:
TreeNode * res;
int sum;
TreeNode * findSubtree(TreeNode * root) {
if (root==NULL) return NULL;
sum=INT_MAX;
int sum=sumofSubtree(root);
return res;
}
int sumofSubtree(TreeNode * root){
if (root==NULL) return 0;
int left=sumofSubtree(root->left);
int right=sumofSubtree(root->right);
if (left+right+root->val<sum)
{sum=left+right+root->val;
res=root;}
return left+right+root->val;
}
};
方法二,构造一个新的答案类型:
class ResultType {
public:
int minSum;
int sum;
TreeNode * node;
ResultType():minSum(INT_MAX),sum(0),node(NULL) {}
ResultType(int _minSum,int _sum, TreeNode * _node):minSum(_minSum),sum(_sum),node(_node) {}
};
class Solution {
public:
TreeNode * findSubtree(TreeNode * root) {
if (root==NULL) return NULL;
return helper(root).node;
}
ResultType helper(TreeNode * root){
if (root==NULL) return ResultType();
ResultType left=helper(root->left);
ResultType right=helper(root->right);
ResultType res=ResultType(left.sum+right.sum+root->val,left.sum+right.sum+root->val,root);
if (left.minSum<res.minSum) {
res.minSum=left.minSum;
res.node=left.node;
}
if (right.minSum<res.minSum) {
res.minSum=right.minSum;
res.node=right.node;
}
return res;
}
};
class Solution {
public:
bool isBalanced(TreeNode * root) {
if (root==NULL) return true;
return (depth(root)!=-1);
}
int depth(TreeNode * root) {
if (root==NULL) return 0;
int left=depth(root->left);
int right=depth(root->right);
if (right==-1 || left==-1 || abs(right-left)>1)
return -1;
else return max(right,left)+1;
}
};
597. 具有最大平均数的子树
使用ResultType记录以每个节点为根的总和、节点个数(记录平均值会牵扯到小数可能不准确),使用全局变量更新最优结果。
class ResultType {
public:
int sum,size;
ResultType():sum(0),size(0) {}
ResultType(int _sum,int _size):sum(_sum),size(_size) {}
};
class Solution {
private:
TreeNode* node;
ResultType data;
public:
TreeNode * findSubtree2(TreeNode * root) {
if (root==NULL) return root;
data.sum=INT_MIN;
data.size=INT_MAX;
helper(root);
return node;
}
ResultType helper(TreeNode * root) {
if (root==NULL) return ResultType();
ResultType left=helper(root->left);
ResultType right=helper(root->right);
ResultType thisnode=ResultType(left.sum+right.sum+root->val,
left.size+right.size+1);
if (data.sum * thisnode.size <thisnode.sum * data.size) {
data=thisnode;
node=root;
}
return thisnode;
}
};
453. 将二叉树拆成链表
方法一,非递归方法:只要这棵树上有左子树就说明没完,找到左子树的最右子树(右子树应该接到的位置),把右子树接过来,左子树变为右子树,左子树赋为NULL。
class Solution {
public:
void flatten(TreeNode *root) {
// write your code here
if (root == NULL) return;
while (root) {
if (root->left) {
TreeNode *pre = root->left;
while (pre->right)
pre = pre->right;
pre->right = root->right;
root->right = root->left;
root->left = NULL;
}
root = root->right;
}
}
};
方法二,递归方法。返回的是已经flatten的子树的根节点:
class Solution {
public:
void flatten(TreeNode *root) {
// write your code here
if (root == NULL) return;
helper(root);
}
TreeNode * helper(TreeNode *root) {
if (root==NULL) return NULL;
TreeNode * left=helper(root->left);
TreeNode * right=helper(root->right);
if (left!=NULL) {
TreeNode * tmp=left;
while (tmp->right!=NULL)
tmp=tmp->right;
tmp->right=right;
root->right=left;
root->left=NULL;
}
return root;
}
};
方法三,另一种递归方法。直接返回左右子树最右下角的位置(应该相接的节点),直接相接,省去了方法二中while循环找最右下角的步骤。
class Solution {
public:
void flatten(TreeNode* root) {
helper(root);
}
TreeNode* helper(TreeNode* root){
if (root==NULL) return NULL;
TreeNode* left=helper(root->left);// left记录了root->left的最右下角的位置,用于接上root->right
TreeNode* right=helper(root->right);//right 记录了root->right最右下角的位置,拼接完成后这将是root的最右下角
if (left!=NULL)
{
left->right=root->right;//将右子树接到左子树最下面
root->right=root->left;//将整棵左子树接到右子树的位置
root->left=NULL;
}
if (right!=NULL) return right;//右子树存在最右下角的位置则优先返回这个位置(因为这个位置将是最右的)
if (left!=NULL) return left;//如果没有右子树的右下角,则左子树的右下角是最后一个位置
return root;//都没有就返回根
}
};