[程序员代码面试指南]二叉树问题-找到二叉树中的最大搜索二叉树(树形dp)

题意

给定一颗二叉树的头节点,已知所有节点的值都不一样,找到含有节点最多的搜索二叉子树,并返回这个树的头节点。

题解

  • 在后序遍历过程中实现。
  • 求解步骤按树形dp中所列步骤。可能性三种:左子树最大、右子树最大、当前节点为根的树。
  • 时间复杂度O(n)

树形dp

使用前提

如果题目求解目标是s规则,则求解流程可以定为以每一节点为根节点的子树在s规则下的每个答案,并且最终答案一定在其中。

步骤

  • 可能性。以根、左子树、右子树的角度考虑。
  • 列出本层所有需要拿到的变量。左右子树要统一。
  • 在递归函数下写:basecase、左右递归、判断可能性、更新要给到上一层的所有变量。

todo

一直未解把用类的子类要怎么搞。子类必须要有实例但OJ测时Main又没实例?

代码

public class ReturnType{
	int min;//最小节点值
	int max;//最大节点值
	int maxSize;//最大BST树的大小
	Node maxRoot;//最大BST树的根节点
	
	ReturnType(int min,int max,int maxSize,Node maxRoot){
		this.min=min;
		this.max=max;
		this.maxSize=maxSize;
		this.maxRoot=maxRoot;
	}
}
public class Main {
	public static void main(String args[]) {
		//test
		Node root=new Node(10);
		Node node1=new Node(11);
		Node node2=new Node(14);
		Node node3=new Node(11);
		Node node4=new Node(15);
		root.left=node1;
		root.right=node2;
		node2.left=node3;
		node2.right=node4;
		
		int maxSize=getMaxBST(root).maxSize;
		System.out.println(maxSize);
	}
	
	public static ReturnType getMaxBST(Node root) {
		if(root==null) {
			return new ReturnType(Integer.MAX_VALUE,Integer.MIN_VALUE,0,null);
		}
		ReturnType lReturn=getMaxBST(root.left);
		ReturnType rReturn=getMaxBST(root.right);
		
		int min=getMin(root.val,lReturn.min,rReturn.min);
		int max=getMax(root.val,lReturn.max,rReturn.max);
		int maxSize=Math.max(lReturn.maxSize, rReturn.maxSize);
		Node maxRoot=maxSize==lReturn.maxSize?lReturn.maxRoot:rReturn.maxRoot;
		if(lReturn.maxRoot==root.left&&rReturn.maxRoot==root.right&&lReturn.max<root.val&&rReturn.min>root.val) {//
			maxSize=lReturn.maxSize+rReturn.maxSize+1;
			maxRoot=root;
		}
		return new ReturnType(min,max,maxSize,maxRoot);
	}
	
	private static int getMin(int... vals) {
		int min=Integer.MAX_VALUE;
		for(int val:vals) {
			if(val<min) {
				min=val;
			}
		}
		return min;
	}
	
	private static int getMax(int... vals) {
		int max=Integer.MIN_VALUE;
		for(int val:vals) {
			if(val>max) {
				max=val;
			}
		}
		return max;
	}	
}