题目一
已知一个搜索二叉树后序遍历的数组posArr, 请根据posArr, 重建出整棵树返回新建树的头节点
例子:
知识点:
- 搜索二叉树的含义
- 前序 中序 后序遍历
详解:
搜索二叉树满足左子树<根<右子数
前序 :根左右
中序 :左根右
后续 :左右根
由定义得最右边的数一定是根,左子树一定比根小,右子树一定比根大,所以可以通过这个规律找到中间左右子树的间隔点,进行深层次递归调用
找到左子数最右边的节点,就是3那个点
方式一:
/**
*
*/
public class Code01_PosArrayToBST {
/**
* 子树节点
*/
public static class Node{
public int value;
public Node left;
public Node right;
public Node(int v){
value=v;
}
}
/**
* 测试
* @param args
*/
public static void main(String[] args) {
Node res=posArrayToBST1(new int[]{2,4,3,6,8,7,5});
System.out.println(res);
}
public static Node posArrayToBST1(int[] posArr){
return process(posArr,0,posArr.length-1);
}
/**
* 递归
* @param arr
* @param left
* @param right
* @return
*/
public static Node process(int[] arr,int left,int right){
if(left>right) return null;
if(right==left){
return new Node(arr[right]);
}
//根节点
Node root=new Node(arr[right]);
//找到分界点
int i=left;
while (arr[i]<arr[right]){
i++;
}
//递归寻找左右子树
root.left= process(arr,left,i-1);
root.right=process(arr,i,right-1);
return root;
}
}
时间复杂度:O(N) 空间复杂度:O(1)
方式二: 改进:在查找左右子树分界点的时候,可以采用二分查找的方式进行查找,将时间复杂度缩短到O(N*log(N))
/**
* 递归:方法二:二分遍历
* @param arr
* @param left
* @param right
* @return
*/
public static Node process2(int[] arr,int left,int right){
if(left>right) return null;
if(right==left){
return new Node(arr[right]);
}
//根节点
Node root=new Node(arr[right]);
//二分法找到分界点,分界点是r找到分界点
int l=left;
int r=right-1;
while (l<=r){
int mid=right+(left-right)>>1;
if(arr[mid]>arr[right]){
r=mid-1;
}else{
l=mid+1;
}
}
//
//递归寻找左右子树
root.left= process(arr,left,r);
root.right=process(arr,r+1,right-1);
return root;
}
题目二
/**
* 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 List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) return res;
ArrayList<TreeNode> contains = new ArrayList<>();
contains.add(root);
while (!contains.isEmpty()) {
List<Integer> q=new ArrayList<>();
int size = contains.size();
for (int i = 0; i < size; i++) {
TreeNode node = contains.remove(0);
q.add(node.val);
if(node.left!=null)contains.add(node.left);
if(node.right!=null)contains.add(node.right);
}
res.add(q);
}
return res;
}
//解法二:递归
List<List<Integer>> list = new ArrayList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
dns(root,0);
return list;
}
public void dns(TreeNode node,int lever){
if(node == null) return;
if(list.size()==lever) list.add(new ArrayList<Integer>());
list.get(lever).add(node.val);
dns(node.left,lever+1);
dns(node.right,lever+1);
}
}