分治法

递归

  • 写递归的技巧
    我的一点心得是:明白一个函数的作用相信它能完成这个任务,千万不要试图跳进细节。千万不要跳进这个函数里面企图探究更多细节,否则就会陷入无穷的细节无法自拔,人脑能压几个栈啊。


二叉树最大深度

遍历游走–没有返回结果–有全局变量—需要两个函数

 private int max;//全局变量在外 不给值
    public int maxDepth(TreeNode root) {
        max=0;
        core(root,1);
        return max;
    }
    public void core(TreeNode root,int depth)
    {
        if(root==null){return ;}
        max=Math.max(max,depth);
        core(root.left,depth+1);
        core(root.right,depth+1);
        
    }

分治法–有返回结果—逻辑在最后那个return,计算结果的时候顺便把逻辑写里面,前面就是不管任何的鲁棒/出口之后,直接调用函数返回你想要的值,最后丢给结果去逻辑

 public int maxDepth(TreeNode root) {
        // 出口
    if(root==null){return 0;}
    int left=maxDepth(root.left);
    int right=maxDepth(root.right);
    //递归
    return Math.max(left,right)+1;
    }


二叉树最小深度

public class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return getMin(root);
    }

    public int getMin(TreeNode root){
       //出口
        if (root == null) {
            return Integer.MAX_VALUE;
        }
     //逻辑
        if (root.left == null && root.right == null) {
            return 1;
        }
     //逻辑+结果
        return Math.min(getMin(root.left), getMin(root.right)) + 1;
    }
}

    public int minDepth(TreeNode root) {
      //鲁棒出口
        if (root == null) return 0;
    //逻辑+结果 
    if (root.left == null) return minDepth(root.right) + 1;
    if (root.right == null) return minDepth(root.left) + 1;
    return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
  /*找到叶子节点结束  只要结点还有左右结点他就不是叶子节点 
  left为空去看right right即使为空了 是叶子节点0+1也加上了遍历到的叶子节点
   left不空 right空 说明还不是叶子节点 那就让结果变为left的结果 比较都是left值
   最后都不空 真的比较两个不同的值
*/
    }

平衡二叉树

//同时思考深度和是否平衡
class ResultType {
    public boolean isBalanced;
    public int maxDepth;
    public ResultType(boolean isBalanced, int maxDepth) {
        this.isBalanced = isBalanced;
        this.maxDepth = maxDepth;
    }
}
public class Solution {
    public boolean isBalanced(TreeNode root) {
        return helper(root).isBalanced;
    }
    
    private ResultType helper(TreeNode root) {
        //鲁棒 出口
        if (root == null) {
            return new ResultType(true, 0);
        }
        //逻辑
        ResultType left = helper(root.left);
        ResultType right = helper(root.right);
        
        //结果
        // subtree not balance
        if (!left.isBalanced || !right.isBalanced) {
            return new ResultType(false, -1);
        }
        
        // root not balance
        if (Math.abs(left.maxDepth - right.maxDepth) > 1) {
            return new ResultType(false, -1);
        }
        
        return new ResultType(true, Math.max(left.maxDepth, right.maxDepth) + 1);
    }


二叉搜索树的最近公共祖先

 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {  //逻辑
        if(root==null){return null;}//很节点为空直接返回空/到叶子节点也返回空
        if(root==p||root==q){return root;}//如果p.q中有是Root的祖先一定是root
        //递归
        TreeNode left=lowestCommonAncestor(root.left,p,q);
        TreeNode right=lowestCommonAncestor(root.right,p,q);
        //结果
        if(left!=null&&right!=null){return root;}//左右都找到了祖先那就是root
        if(left!=null){return left;}//左子树找到了祖先
        if(right!=null){return right;}//右子树找到了祖先
        return null;//找不到祖先
    }

二叉树,找到根节点出发到任意结点结束 的 最大路径和
root->leaf

public int maxSum(TreeNode root)
{
if(root==null){return 0;}
int left=maxSum(root.left);
int right=maxSum(root.right);
//递归+结果
return Math.max(left,right)+root.val;
}

root->any
如果当前的路径和已经比0还小我们就不会要它,直接丢弃,清空为0
在这里插入图片描述

public int maxSum(TreeNode root)
{
if(root==null){return 0;}
int left=maxSum(root.left);
int right=maxSum(root.right);
//递归+结果
return Math.max(0,Math.max(left,right))+root.val;
}

any->any
在这里插入图片描述
在这里插入图片描述
情况1:根节点 右子树 如果负数很多 最大路径只在左子树
情况2:最大路径只在右子树
情况3:最大路径横跨左右子树,
先在左子树中 求左子树的根节点到任意节点的最大路径和
右子树中求 右子树的根节点到任意结点的最大路径和
最后把上面两个路径和相加再加上根节点的值 就是整体最大

根据以上分析 前两种情况 要先求左右子树的root2Any(root->any )并且最大值作为本轮的any2ANy
第三种情况:=左右子树谁的any->any路径和大 就 去和左+右+根比较

因为any2Any是我们要求的,但是root2Any是我们依赖的,有多个因素影响我们的结果,所以要写一个结果类型,和上面平衡二叉树,需要求高度的同时要求是否平衡一样

class ResultType
{
  int root2Any;
  int any2Any;
  public ResultType(int a,int b){this.root2Any=a; this.any2Any=b;}
}
public class Solution
{
 public int maxSum(TreeNode root)
 {
   ResultType result=helper(root);
  return result.any2Any;
}


private  ResultType helper(TreeNode root)
{
if(root==null)
{
 return new ResultType(Intger.MIN_VALUE,Intger.MIN_VALUE);
}
//分
ResultType left=helper(root.left);
ResultType right=helper(root.right);
//治
int root2Any=Math.max(0,Math.max(left.root2Any,right.root2Any))+root.val;

int any2Any=Math.max(left.any2Any,right.any2Any);//最大路径完全在左边或这右边
any2Any=Math.max(any2Any,Math.max(0,left.root2Any)+Math.max(0,right.root2Any)+root.val);//第三种情况 左+root+右
return new ResultType(root2Any,any2Any);
}
}

BST 二叉搜索树/二叉排序树

binary seratch/sorted tree

左子树《=根
右子树》根

左子树《根
右子树》=根
中序遍历是一个升序序列
在这里插入图片描述
在这里插入图片描述
层遍历的DFS实现方法
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值