剑指offer 树 递归

题目

剑指 Offer 55 - II. 平衡二叉树

输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

    public boolean isBalanced(TreeNode root) {
     if(root==null) return true;

 return Math.abs(height(root.left)-height(root.right))<=1
           &&isBalanced(root.left)&&isBalanced(root.right);
    }

   public int height(TreeNode root){ 
       if(root==null) return 0;
      return Math.max(height(root.left),height(root.right))+1;
   }

剑指 Offer 28. 对称的二叉树

在这里插入图片描述

 public boolean isSymmetric(TreeNode root) {
    
    if(root==null) return true;

     return helper(root.left,root.right);

    
     
    }

     public boolean helper(TreeNode A,TreeNode B){
        if(A==null&&B==null) return true;
 
        if(A==null||B==null) return false;

        return A.val==B.val&&helper(A.right,B.left)&&helper(A.left,B.right); 
     }
 

剑指 Offer 27. 二叉树的镜像

在这里插入图片描述

    public TreeNode mirrorTree(TreeNode root) {
       
        if(root==null) return root;  

        TreeNode temp=mirrorTree(root.left);

        root.left=mirrorTree(root.right);

        root.right=temp;
        
        return root;
  
    }

剑指 Offer 32 - I. 从上到下打印二叉树

在这里插入图片描述

 public int[] levelOrder(TreeNode root) {
          
        ArrayList<Integer> list=new ArrayList<>();
        ArrayList<TreeNode> stack=new ArrayList<>(); 
       if(root==null)return new int[0];
        
        stack.add(root);


        while(!stack.isEmpty()){
            TreeNode node=stack.remove(0);

            if(node.left!=null){
               stack.add(node.left);
            }

            if(node.right!=null){
                 stack.add(node.right);
            }
            list.add(node.val);
        }
        
        int Array[]=new int[list.size()];
        
        int j=0;
        int i=0;
        while(j<list.size()){
                Array[j++]=list.get(i++);
        }

            return Array;
        } 

剑指 Offer 32 - II. 从上到下打印二叉树 II

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
在这里插入图片描述

    public List<List<Integer>> levelOrder(TreeNode root) {
      List<List<Integer>> res=new ArrayList<>();
        Queue<TreeNode> stack=new LinkedList<>();
        if(root!=null) stack.add(root);

        while(!stack.isEmpty()){
         List<Integer> list=new ArrayList<>();
         int n=stack.size();
            for (int i = 0; i <stack.size() ; i++) {
                TreeNode temp=stack.poll();
                list.add(temp.val);
                 if(temp.left!=null) stack.add(temp.left);
                if(temp.right!=null) stack.add(temp.right);  
            }
            res.add(list);
        }
       return res;
    }

剑指 Offer 32 - III. 从上到下打印二叉树 III

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
在这里插入图片描述

public List<List<Integer>> levelOrder ( TreeNode root) {
        List<List<Integer>> res=new ArrayList<>();
        Queue<TreeNode> stack=new LinkedList<>();
        if(root!=null) stack.add(root);

        while(!stack.isEmpty()){
            LinkedList<Integer> list=new LinkedList<>();
            int n=stack.size();
            for (int i = 0; i <n ; i++) {
                TreeNode node=stack.poll();
//                list.add(node.val);
                if(res.size()%2==0)
                    list.addLast(node.val);
                else
                    list.addFirst(node.val);
                if(node.left!=null) stack.add(node.left);
                if(node.right!=null) stack.add(node.right);
            }
            res.add(list);
        }
        return res;
    }

剑指 Offer 33. 二叉搜索树的后序遍历序列

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。

    public boolean verifyPostorder(int[] postorder) {
         //左<根<右
   
     return  dfs(postorder,0,postorder.length-1);
    }

      public boolean dfs(int arr[],int l,int r){
            if(l>=r) return true;
            int p=l;
            //向右遍历找最左子树的根结点下一个节点
            while(arr[p]<arr[r]) p++;
            int m=p;
            while(arr[p]>arr[r]) p++;

       return p==r&&dfs(arr,l,m-1)&&dfs(arr,m,r-1);
      } 

剑指 Offer 34. 二叉树中和为某一值的路径

输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。

   ArrayList<Integer> list=new ArrayList<>();
     ArrayList<List<Integer>> res=new ArrayList<>(); 
    public List<List<Integer>> pathSum(TreeNode root, int sum) {  
      recur(root,sum);  
      return res;
    }
 
    public void recur(TreeNode root,int sum){
      if(root==null) return;
      sum-=root.val;
      list.add(root.val);
      if(sum==0&&root.left==null&&root.right==null){
          res.add(new ArrayList(list));
      }
       recur(root.left,sum);
       recur(root.right,sum);

       //把左节点放进去再放右结点
       list.remove(list.size()-1);   
    }

面试题34 二叉树中和为某一值的路径

给定一个二叉树和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径,

 public boolean hasPathSum (TreeNode root, int sum) {
      if(root==null) return false;
        
       if(sum-root.val==0&&root.left==null&&root.right==null) return true; 
        
        return hasPathSum(root.left,sum-root.val)||hasPathSum(root.right,sum-root.val); 
    }     
}

##Leetcode 437. 路径总和 III

在这里插入图片描述

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
     
     int count=0;
    public int pathSum(TreeNode root, int sum) {
         if(root==null) return 0;
         //找和为sum的所有路径值
        dfs(root,sum);
         //从左子节点寻找路径
         pathSum(root.left,sum);
         //从右子节点寻找路径
         pathSum(root.right,sum);
          return count;
    }



    public void dfs(TreeNode root,int sum){
        if(root==null) return ;  
         sum-=root.val;
        if(sum==0)  count++; 

        dfs(root.left,sum);
        dfs(root.right,sum);      
    } 
}

剑指 Offer 68 - II. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

   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) return right;
        if(right==null) return left;
        return root;
        
    }

面试题57 二叉树的下一个节点

题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

    public TreeLinkNode GetNext(TreeLinkNode pNode)
    {
        //树空
      if(pNode==null){
       return null;
  }
//结点存在右子树,下一个结点为pNode右子树的左节点
if(pNode.right!=null){
pNode = pNode.right;//当前节点的右子节点
while(pNode.left!=null){
pNode=pNode.left;
}
return pNode;
}

//结点不存在右子树,pNode为左节点,下一个结点为该节点父节点;否则继续向上找
while(pNode.next!=null){
 
    if( pNode.next.left==pNode)
          return  pNode.next;
       pNode=pNode.next;
        }
        return null;
        
    }

面试题07 重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

 public TreeNode buildTree(int[] preorder, int[] inorder) {
       if(preorder.length==0||inorder.length==0) return null;


        int n=inorder.length;
        int root= preorder[0];
     //找到中序遍历i的序列号index
        int index = 0;

     for (int i = 0; i < n; i++) {
            if(inorder[i]==root ){
                index=i;
                break;
            }
        }

     TreeNode root1=new TreeNode(root);
     root1.left=buildTree(Arrays.copyOfRange(preorder,1,index+1),Arrays.copyOfRange(inorder,0,index));
     root1.right=buildTree(Arrays.copyOfRange(preorder,index+1,n),Arrays.copyOfRange(inorder,index+1,n));
     return root1;
    }

剑指 Offer 36. 二叉搜索树与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

为了让您更好地理解问题,以下面的二叉搜索树为例:

 class Solution {
    // 1. 中序,递归,来自解题大佬
    Node pre, head;
    public Node treeToDoublyList(Node root) {
        // 边界值
        if(root == null) return null;
        dfs(root);

        // 题目要求头尾连接
        head.left = pre;
        pre.right = head;
        // 返回头节点
        return head;
    }
    void dfs(Node cur) {
        // 递归结束条件
        if(cur == null) return;
        dfs(cur.left);
        // 如果pre为空,就说明是第一个节点,头结点,然后用head保存头结点,用于之后的返回
        if (pre == null) head = cur;
        // 如果不为空,那就说明是中间的节点。并且pre保存的是上一个节点,
        // 让上一个节点的右指针指向当前节点
        else if (pre != null) pre.right = cur;
        // 再让当前节点的左指针指向父节点,也就连成了双向链表
        cur.left = pre;
        // 保存当前节点,用于下层递归创建
        pre = cur;
        dfs(cur.right);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值