二叉树中难题 (Java)

KY11二叉树的遍历及构建(中难)
编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。 输入描述: 输入包括1行字符串,长度不超过100。 输出描述: 可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。 每个输出结果占一行。 示例1入: abc##de#g##f### 复制 输出: c b e g d f a

package Tree;
import java.util.*;
import java.util.Scanner;


	class TreeNode{
		public char val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(char val){
        	this.val=val;
        }
	}
	
     public class Tree{
     public static int i=0;
	public static TreeNode createTree(String str) {//字符串
		TreeNode root = null;                //这一段思路:先创建根,再创建左和右,
		                                     //再创建孩子的根,在创建左右。
		if(str.charAt(i)!='#') {
			root = new TreeNode (str.charAt(i));
			i++;
			root.left = createTree(str);
			root.right = createTree(str);
		}else {
			i++;
			
		}
		return root;
	}
public static void inorder(TreeNode root) {
	if(root==null)return;
	inorder(root.left);
	System.out.println(root.val+" ");
	inorder(root.right);
}
	
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		while(scan.hasNextLine()) {
			String str = scan.nextLine();
			TreeNode root = createTree(str);
			inorder(root);
		}
		
	}
	
}




236. 二叉树的最近公共祖先

难度:中等

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

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

 

示例 1:

af937f5a27c7974073aa712eff6b3852.png

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

 思路:一共有以下三种情况

3677f9ac15214c5bab920b24934ef7f3.png

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
   
 public TreeNode lowestCommonAncestor(TreeNode root,TreeNode q,TreeNode p) {
	  if(root==null)return null;
      if(root==p||root==q)
		  return root;
	
	  TreeNode leftRet =lowestCommonAncestor(root.left,q,p) ;
	  TreeNode rightRet = lowestCommonAncestor(root.right,q,p);
	  if(leftRet!=null&&rightRet!=null) {
		   return root;
	  }
	  else if(leftRet!=null) {
			return leftRet;
	    }
     else if(rightRet!=null) {
	       return rightRet;
     }
     return null;
    }
}

 

JZ36 二叉搜索树与双向链表

描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示

ccc175eff01e608c8c0b7019c462423b.png

 

数据范围:输入二叉树的节点数 0 \le n \le 10000≤n≤1000,二叉树中每个节点的值 0\le val \le 10000≤val≤1000
要求:空间复杂度O(1)O(1)(即在原树上操作),时间复杂度 O(n)O(n)

 

注意:

1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继
2.返回链表中的第一个节点的指针
3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构

4.你不用输出双向链表,程序会根据你的返回值自动打印输出

输入描述:

二叉树的根节点

返回值描述:

双向链表的其中一个头节点。

示例1

输入:

{10,6,14,4,8,12,16}

复制返回值:

From left to right are:4,6,8,10,12,14,16;From right to left are:16,14,12,10,8,6,4;

复制说明:

输入题面图中二叉树,输出的时候将双向链表的头节点返回即可。 

 

 思路写一个中序遍历,把中间的输出改成,设一个prev,让pCur.left=prev; prev.right=pCur。再让pCur回溯向上移,prev=pCur。

1f81a1fa2a20440ca6554af915a30d78.png

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/


  public class Solution {
       TreeNode prev=null;
       public void ConvertChild(TreeNode pCur) {
       if(pCur==null)return;
       ConvertChild(pCur.left);
       pCur.left=prev;
       if(prev!=null){
           prev.right=pCur;
    }
   
        prev=pCur;
     ConvertChild(pCur.right);
    
    }
    public TreeNode Convert(TreeNode pRootOfTree) {

    // write code here
       if(pRootOfTree==null)return null;
       ConvertChild(pRootOfTree);
       TreeNode head = pRootOfTree;
       while(head.left!=null){
           head=head.left;
    }
       return head;
    }
}

105. 从前序与中序遍历序列构造二叉树

难度中等

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

 

示例 1:

d503adeffbea4f8cb4f666bfed0cf561.png
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
示例 2:

输入: preorder = [-1], inorder = [-1]
输出: [-1]

1b5488c95ba94f8b97903f764f205add.png

/**
 * 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 {
 
    public int preIndex=0;
    public TreeNode buildTreeChild(int[]preorder,int[] inorder,int inbegin,int inend){
    if(inbegin>inend)return null;
    TreeNode root=new TreeNode(preorder[preIndex]);
    int rootIndex = findInorderRootIndex(inorder,inbegin,inend,preorder[preIndex]);
    preIndex++;
     root. left = buildTreeChild(preorder,inorder,inbegin,rootIndex-1);
     root. right = buildTreeChild(preorder,inorder,rootIndex+1,inend);
    return root;
}
public int findInorderRootIndex(int[]inorder,int inbegin,int inend,int val){
    for(int i=inbegin;i<=inend;i++){
        if(inorder[i]==val){
        return i;
        }
    }
    return -1;
}
   public TreeNode buildTree(int[] preorder, int[] inorder) {
    return buildTreeChild(preorder,inorder,0,inorder.length-1);
    }
}

606. 根据二叉树创建字符串

 

给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。

空节点使用一对空括号对 "()" 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

 

示例 1:

cc3e60ed1b4940709b28375e8328d72e.png
输入:root = [1,2,3,4]
输出:"1(2(4))(3)"
解释:初步转化后得到 "1(2(4)())(3()())" ,但省略所有不必要的空括号对后,字符串应该是"1(2(4))(3)" 。

 

这个题还需要自己多画几颗二叉树感受一下递归。’

 

/**
 * 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 {
     public void tree2strChild(TreeNode t,StringBuilder sb){
     if(t==null)return;
     sb.append(t.val);  //根不为空 添加根
     if(t.left!=null){     //根左节点不空 添加(递归根左节点)
         sb.append("(");
         tree2strChild(t.left,sb);
         sb.append(")");
        }else{            //根左节点为空。看根右节点空就不管,看根右节点不空就 添加()
         if(t.right == null){
             return;
         }else{
             sb.append("()");
         }
     
     }      // 这个if语句执行完了    
     if(t.right==null){  //根左节点为空。看根右节点空就不管,看根右节点不空就 添加(递归右节点)
         return;
     }else{
         sb.append("(");
          tree2strChild(t.right,sb);
          sb.append(")");
     }
     }
   
 public String tree2str(TreeNode root) {
        if(root==null)return null;
        StringBuilder sb=new StringBuilder();
        tree2strChild(root,sb);
        return sb.toString();//StringBuilder变成String
    }
}

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值