二叉树

二叉树类型

  关于二叉树类型中的题,那些递归的内容大家千万别陷进去,因为你用你的小脑袋瓜去递归这些东西只会让你越来越迷糊,我们只要考虑某一个节点 的情况就可以,剩下的递归交给计算机就可以了。

  1. 力扣226题:翻转二叉树在这里插入图片描述
class Solution {
    public TreeNode invertTree(TreeNode root) {
        //base case
        if(root==null)return null;
        //交换左右子节点
        TreeNode tmp=root.left;
        root.left=root.right;
        root.right=tmp;
        //让子节点的子节点进行交换
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }
}
  1. 力扣116题: 填充每个节点的下一个右侧节点指针
    在这里插入图片描述
    在这里插入图片描述
class Solution {
    //主函数
    public Node connect(Node root) {
        if(root==null) return null;
         connectTwoNode(root.left,root.right);
         return root;
    }
    //辅助方法
    void connectTwoNode(Node root1,Node root2){
        if(root1==null||root2==null){
            return;
        }
        //先连接传进来的两个子节点
        root1.next=root2;
        //分别连接两个子节点下面的子节点
        connectTwoNode(root1.left,root1.right);
        connectTwoNode(root2.left,root2.right);
        //连接左右子节点交汇处的节点
        connectTwoNode(root1.right,root2.left);
    }
}
  1. 力扣114题: 二叉树展开为链表
    在这里插入图片描述
    在这里插入图片描述
class Solution {
    public void flatten(TreeNode root) {
        //base case
        if(root==null)return;

         flatten(root.left);
         flatten(root.right);
         //1.左右子树被拉成一个链条
         TreeNode nodeLeft=root.left;
         TreeNode nodeRight=root.right;

         //将左子树赋到右子树
         root.left=null;
         root.right=nodeLeft;

         //将原先的左子树接到现在的右子树后面
         TreeNode p=root;
         while(p.right!=null){
             p=p.right;
         }
         p.right=nodeRight;
    }
}
  1. 力扣654题:最大二叉树
    在这里插入图片描述
    在这里插入图片描述
class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
            return build(nums,0,nums.length-1);
    }
    TreeNode build(int[] nums,int lo,int hi){
        //如果传进来的最低的下标大于最大的说明数组为空
        if(lo>hi)return null;
        //假设最大值的下标为index
        int index=-1;
        int max=Integer.MIN_VALUE;
        for(int i=lo;i<=hi;i++){
            if(nums[i]>max){
                max=nums[i];
                index=i;
            }
        }
        TreeNode root= new TreeNode(max);
        //递归子树
        root.left=build(nums,lo,index-1);
        root.right=build(nums,index+1,hi);
        return root;
    }
}
  1. 力扣105题.从前序与中序遍历序列构造二叉树
    在这里插入图片描述
class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
    }
    TreeNode build(int[] preorder,int preStart,int preEnd,int[] inorder,int inStart,int inEnd){
        //base case
        if(preStart>preEnd)return null;
        //root 节点的值为前序遍历的第一个元素
        int rootVal=preorder[preStart];
        int index=0;
        for(int i=0;i<preorder.length;i++){
            if(rootVal==inorder[i]){
                index=i;
                break;
            }
        }
        int leftLength=index-inStart;
        TreeNode root=new TreeNode(rootVal);
        root.left=build(preorder,preStart+1,preStart+leftLength,inorder,inStart,index-1);
        root.right=build(preorder,preStart+leftLength+1,preEnd,inorder,index+1,inEnd);
        return root;
    }

}
  1. 力扣106题. 从中序与后序遍历序列构造二叉树

    在这里插入图片描述
class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        return build(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
    }
    TreeNode build(int[] inorder,int inStart,int inEnd,int[] postorder,int postStart,int postEnd){
        //base case
        if(inStart>inEnd)return null;
        //根节点就是后序遍历的最后一位
        int rootVal=postorder[postEnd];
        int index=0;
        for(int i=inStart;i<=inEnd;i++){
            if(rootVal==inorder[i]){
                index=i;
                break;
            }
        }
        int leftSize=index-inStart;
        TreeNode root =new TreeNode(rootVal);
        root.left=build(inorder,inStart,index-1,postorder,postStart,postStart+leftSize-1);
        root.right=build(inorder,index+1,inEnd,postorder,postStart+leftSize,postEnd-1);
        return root;
    }
}
  1. 力扣652题:寻找重复的子树
    在这里插入图片描述
class Solution {
    //记录出现重复的子树的集合
    List<TreeNode> res=new ArrayList<>();
    //记录所有子树和出现的次数
    HashMap<String,Integer> memo=new HashMap<>();
    public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
        traverse(root);
        return res;
    }
    /*辅助函数*/
    String traverse(TreeNode root){
        if(root==null){
            return "#";
        }
        String left=traverse(root.left);
        String right=traverse(root.right);
        //后序遍历
        String subTree=left+","+right+","+root.val;
        //出现的频率,如果不存在默认为0
        int freq=memo.getOrDefault(subTree,0);
        //如果存在1个就添加进集合中
        if(freq==1){
            res.add(root);
        }
        memo.put(subTree,freq+1);
        return subTree;


    }
}
  1. 力扣230题: 二叉搜索树中第K小的元素
    在这里插入图片描述
    在这里插入图片描述
class Solution {
    //结果
    int res=0;
    //元素排名
    int rank=0;
    public int kthSmallest(TreeNode root, int k) {
        traverse(root,k);
        return res;
    }
    /*中序遍历,中序遍历的结果是按照从小到大排的*/
    void traverse(TreeNode root,int k){
        if(root==null){
            return;
        }
        traverse(root.left,k);
        rank++;
        if(k==rank){
            res=root.val;
            return;
        }
        traverse(root.right,k);
    }
}
  1. 力扣538题: 把二叉搜索树转换为累加树
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
class Solution {
    //记录累加和
    int sum=0;
    public TreeNode convertBST(TreeNode root) {
        traverse(root);
        return root;
    }
    /*中序遍历,但是与之前的不同的是这次的是降序排列,那么这道题就变成了累加和,也就是说遍历顺序为:右子树——节点——左子树*/
    void traverse(TreeNode root){
        if(root==null){
            return;
        }
        traverse(root.right);
        sum+=root.val;
        root.val=sum;
        traverse(root.left);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

blog_xsong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值