/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
1.maximum-depth-of-binary-tree
public int maxDepth(TreeNode root) {
if(root==null){
return 0;
}
return Math.max(maxDepth(root.left),maxDepth(root.right))+1; // +1指的是节点本身
}
2.balanced-binary-tree
题解说明
节点,若不平衡,你的高度就是个-1,且会被历史铭记,出栈也不放过你
public boolean isBalanced(TreeNode root) {
return helper(root)>=0;
}
public int helper(TreeNode root){
if(root == null){
return 0;
}
int l = helper(root.left);
int r = helper(root.right);
if(l==-1 || r==-1 || Math.abs(l-r)>1) return -1; //非平衡点return -1,且会将-1一直return上去
return Math.max(l,r) +1; //平衡点时返回高度
}
3.binary-tree-maximum-path-sum
题解说明
左右齐心,贡献最大,争取整条路径最大,要不还是会被舍弃
class Solution {
private int maxSum = Integer.MIN_VALUE; //这个赋值很关键
//实例变量是存储在堆中,每次递归的操作都会使其改变
public int maxPathSum(TreeNode root) {
maxGain(root);
return maxSum;
}
private int maxGain(TreeNode root){
if(root==null){
return 0;
}
// 递归计算左右子节点的最大贡献值
// 只有在最大贡献值大于 0 时,才会选取对应子节点
int left = Math.max(maxGain(root.left),0);
int right = Math.max(maxGain(root.right),0);
int newPathSum = root.val+left + right;// 节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值
maxSum = Math.max(maxSum,newPathSum); // 更新答案
//maxSum初始赋值为Integer.MIN_VALUE的原因,要不最大路径和为负数还返回0
return root.val+Math.max(left,right); // 返回节点的最大贡献值
}
}
4.lowest-common-ancestor-of-a-binary-tree
题解说明
p,q同时在当前子树中:left,right非空,return鹊桥。继续出栈的路上只有你俩的鹊桥,另一个分支都为null
p,q不同时在当前子树:保留在的那个,等待另一个出现,邂逅在上面的某个节点
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null||root==p||root==q)return root;
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
//if(left==null&&right==null)return null;
//if(left==null)return right; //右非空
//if(right==null)return left;
//return root; //都非空
if(left!=null&&right!=null)return root; //在当前的子树
return left!=null?left:right; //保留非空
}
5.binary-tree-level-order-traversal
题解说明
基于双亲层节点数,去界定孩子层范围
public List<List<Integer>> levelOrder(TreeNode root) {
LinkedList<TreeNode> queue = new LinkedList<>(); //ArrayList没有poll(),LinkedList有
List<List<Integer>> res = new ArrayList<>();
if(root!=null){
queue.add(root);
}
while(!queue.isEmpty()){
int size = queue.size(); //为双亲层结点数,基于此去添加当前孩子层
List<Integer> level = new ArrayList<>(); //创建空对象
for(int i=0;i<size;i++){
//添加中
TreeNode curNode = queue.poll();
if(curNode.left!=null){
queue.add(curNode.left);
}
if(curNode.right!=null){
queue.add(curNode.right);
}
level.add(curNode.val);
}
res.add(level); //可改编版
}
return res;
}
改编版: 底朝天:res.add(0,level) 锯齿状:if(res.size()%2!=0)Collections.reverse(level); res.add(level);
还有类似的如:左视图、右视图
public void leftView(TreeNode root) {
LinkedList<TreeNode> queue = new LinkedList<>(); //List没有poll(),LinkedList有
if(root!=null){
queue.add(root);
}
while(!queue.isEmpty()){
int size = queue.size(); //为双亲层结点数,基于此去添加当前孩子层
for(int i=0;i<size;i++){
//添加中
TreeNode curNode = queue.poll();
if(i==1){
//说明为双亲层从左到右第一个,即最左边的 右视图的话则 i==size-1
System.out.print(poll.val + " ");
}
if(curNode.left!=null){
queue.add(curNode.left);
}
if(curNode.right!=null){
queue.add(curNode.right);
}
}
}
}
6.validate-binary-search-tree
题解说明:二叉搜索(排序)树,中序遍历时数值按照从小到大依次。所以验证的话只需要中序判断当前值与前驱值
long pre = Long.MIN_VALUE; //要恒小于中序的第一个值
public boolean isValidBST(TreeNode root) {
if(root==null){
return true;
}
if(!isValidBST(root.left)){
//左子树
return false;
}
// 访问当前节点:如果当前节点小于等于中序遍历的前一个节点,说明不满足BST,返回 false;否则继续遍历
if(root.val<=pre){
return false; //一旦一个为false,就一路false直至出栈
}
pre = root.val; //左右节点的前驱:右节点前驱显然;对于左节点,每次都是先比较完事后,再赋值,相当于保存的是过去时
return isValidBST(root.right); //右子树
}
7.insert-into-a-binary-search-tree
题解说明:目标位置有两种情况:有元素则继续入栈,无元素则开辟空间占位(是新空间,双亲节点的孩子变量得指向,要不就成孤儿了
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root==null){
return new TreeNode(val); //开辟新空间返回,新生儿
}
if(val<root.val){
root.left = insertIntoBST(root.left,val); //指向其左孩子
}else{
root.right = insertIntoBST(root.right,val); //指向其右孩子
}
return root; //原样返回,出生n多年的孩子
}