https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/
给定一颗二叉树,输出包含所有最深叶子结点的最小子树的根节点。
解法一:
先使用dfs计算最大深度deep和最大深度的叶子结点数cnt,然后后序遍历,对每个节点再使用dfs计算以该节点为根节点的子树中所含最大深度的节点数,最先找到的最大深度为节点数目等于cnt的节点即为答案。
class Solution{ public: int deep=-1,cnt=0; TreeNode* res=NULL;
TreeNode* subtreeWithAllDeepest(TreeNode* root){ cntdeepest(root, 0); backorder(root, 0); return res; } void cntdeepest(TreeNode * root, int d){ if(d>deep){ deep=d; cnt=1; }else if(d==deep) cnt++; if(root->left != NULL) cntdeepest(root->left,d+1); if(root->right != NULL) cntdeepest(root->right, d+1); } void backorder(TreeNode* root, int d){ if(root == NULL) return; if(res != NULL) return; backorder(root->left, d+1); backorder(root->right, d+1); int all = calcdeepest(root, d); if(res==NULL && all == cnt) res = root; } int calcdeepest(TreeNode* root, int d){ if(root == NULL) return 0; if(d == deep) return 1; int left=0, right=0; if(root->left != NULL) left = calcdeepest(root->left, d+1); if(root->right != NULL) right = calcdeepest(root->right, d+1); int all = left+right; return all; } };
这种解法若节点数过多,会比较费时。
解法二:官方题解
dfs(TreeNode* root, depth)返回以root为根节点的子树中包含该子树上所有深度最深叶节点的指针和最大深度。
若为子节点,返回其指针和深度。
若左子树的深度大于右子树,说明只有左子树中包含深度最大的叶节点。
若其中一个子树为空,说明另外一棵子树包含着深度最深的节点。
若两子树深度相同,说明该节点是当前包含该子树上所有深度最深节点的最小子树根节点。
struct Return{ TreeNode* root_; int depth_; Return(TreeNode* root, int depth):root_(root),depth_(depth){} }; class Solution { public: TreeNode* subtreeWithAllDeepest(TreeNode* root) { Return ret = dfs(root, 0); return ret.root_; } Return dfs(TreeNode* root, int depth){ if(root == NULL) return Return(NULL, 0); if(root->left == NULL && root->right == NULL) return Return(root, depth); Return left = dfs(root->left, depth+1); Return right = dfs(root->right,depth+1); if(left.root_ == NULL && right.root_ == NULL) //叶节点 return Return(root, depth); else if(left.root_ == NULL) //左子树为空的中间节点 return right; else if(right.root_ == NULL) //右子树为空的中间结点 return left; else if(left.depth_ == right.depth_) return Return(root, left.depth_); else return left.depth_>right.depth_?left:right; } };