【题目】给定一棵二叉树的头节点head,已知其中所有节点的值都不一样,找到含有节点最多的搜索二叉树,并返回这颗子树的头节点。
【要求】如果节点数为N,要求时间复杂度为O(N),额外空间复杂度为O(h),h为二叉树的高度
【解题】树形dp套路
第一步:分析答案的可能性
- 第一种:X为头节点的子树中,最大的搜索二叉树就是X的左子树中的最大搜索二叉子树。即答案来自左子树
- 第二种:X为头节点的子树中,最大的搜索二叉树就是X的右子树中的最大搜索二叉子树。即答案来自右子树
- 第三种:若X左子树上的最大搜索二叉子树是X左子树的全体,X右子树上的最大搜索二叉子树是X右数全体,并且X的值大于X的左子树所有节点的最大值,且小于X右子树所有节点的最小值,那么X为头节点的子树中,最大的搜索二叉子树是以X为头节点的全体。
第二步:列出需要的信息
- 若为第一种、第二种情况,则需要知道左子树和右子树上的最大搜索二叉子树的头部,记为;leftBSTHead,rightBSTHead;
- 左子树和右子树上最大二叉搜索子树的大小,记为leftBSTSize,rightBSTSize;
- 左子树的最大值和右子树的最小值,leftMax,rightMin
第三步:整合信息
左右子树都需要最大搜索二叉子树的头节点以及大小这两个信息,但是左子树只需要最大值,右子树只需要最小值,那么合并变成统一要求:左右子树的最大值和最小值
struct ReturnType{
TreeNode* maxBSRHead;
int maxBSTSize;
int minValue;
int maxValue;
ReturnType(TreeNode* maxBSRHead,int maxBSTSize,int minValue,int maxValue){
this->maxBSRHead = maxBSRHead;
this->maxBSTSize = maxBSTSize;
this->minValue = minValue;
this->maxValue = maxValue;
}
};
第四步:设计递归函数,包括递归的base case,默认得到左树和右树的所有信息,整合信息,返回第三步的信息结构这四个步骤
ReturnType* process(TreeNode* X){
/*base case:若子树为空,最小值为系统最大,最大值为系统最小*/
if(X == NULL)
return new ReturnType(NULL,0,INT_MAX,INT_MIN);
/*默认得到左右子树的所有信息*/
ReturnType* lData = process(X->left);
ReturnType* rData = process(X->right);
/*信息整合*/
int minValue = min(X->value,min(lData->minValue,rData->minValue));
int maxValue