您的位置:首页 > Web前端

剑指offer 树

2015-09-19 13:19 369 查看
二叉树

完全二叉树



二叉搜索树

AVL树

红黑树

Trie树

遍历

1.1 题目(面试题23):分层打印二叉树

解法一:广度优先,借助队列数据结构

public class Solution {
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> array=new ArrayList<Integer>();
if(root==null)
return array;
Queue<TreeNode> q=new LinkedList<TreeNode>();
q.offer(root);
while(!q.isEmpty()){
TreeNode temp=q.poll();
array.add(temp.val);
if(temp.left!=null){
q.offer(temp.left);
}
if(temp.right!=null){
q.offer(temp.right);
}
}
return array;
}
}


相关题目

题目1:分层打印成多行

public class Solution {
ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer> > result=new ArrayList<ArrayList<Integer> > ();
if(pRoot==null)
return result;

Queue<TreeNode> q= new LinkedList<TreeNode>();
q.offer(pRoot);

while(!q.isEmpty()){
int start=0;
int end=q.size();
ArrayList<Integer> temp=new ArrayList<Integer>();

while(start<end){
TreeNode node=q.poll();
temp.add(node.val);
if(node.left!=null)
q.offer(node.left);
if(node.right!=null)
q.offer(node.right);
start++;
}
result.add(temp);
}
return result;
}
}
题目2:之字形打印二叉树

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer> > result=new ArrayList<ArrayList<Integer> >();
if(pRoot==null)
return result;

Queue<TreeNode> q=new LinkedList<TreeNode>();
q.offer(pRoot);
int count=1;
while(!q.isEmpty()){
int start=0;
int end=q.size();
ArrayList<Integer> temp= new ArrayList<Integer>();
while(start<end){
TreeNode node=q.poll();
temp.add(node.val);
if(node.left!=null)
q.offer(node.left);
if(node.right!=null)
q.offer(node.right);
start++;
}
if(count%2==1)
result.add(temp);
else{
result.add(reverse(temp));
}
count++;
}
return result;
}

private  ArrayList<Integer> reverse( ArrayList<Integer> temp){
ArrayList<Integer> result=new ArrayList<Integer>();
for(int i=temp.size()-1;i>=0;i--){
result.add(temp.get(i));
}
return result;
}
}


1.2 题目(面试题6):重建二叉树

解法一:递归,前序序列和中序序列或者后序序列和中序序列

import java.util.Arrays;
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre.length!=in.length || pre==null || in==null)
return null;
if(pre.length==0 && in.length==0)
return null;

TreeNode root=new TreeNode(pre[0]);
if(in.length==1)
return root;
int i=0;
for(;i<in.length;i++){
if(in[i]==root.val)
break;
}
if(i>0)
root.left=reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(in,0,i));
if(i<in.length-1)
root.right=reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(in,i+1,in.length));
return root;
}
}

1.3 题目(面试题24):二叉搜索树的后续遍历序列

import java.util.Arrays;
public class Solution {
public boolean VerifySquenceOfBST(int [] sequence) {
int len=sequence.length;
if(len==0 || sequence==null)
return false;
int root=sequence[len-1];
int i=0;
for(;i<len-1;i++){
if(sequence[i]>root)
break;
}
int j=i;
for(;j<len-1;j++){
if(sequence[j]<root)
return false;
}
boolean left=true;
boolean right=true;
if(i>0){
left=VerifySquenceOfBST(Arrays.copyOfRange(sequence, 0, i));
}
if(i<sequence.length-1)
right=VerifySquenceOfBST(Arrays.copyOfRange(sequence, i, sequence.length-1));
return (left && right);
}
}
相关题目:

输入一个数组,判断该数组是不是某二叉搜索树的前序遍历结果

1.4 题目(面试题58):二叉树的下一个结点
1.5 题目(面试题64):二叉搜索树的第K个结点
解法一:前序序列

public class Solution {
int k;
TreeNode KthNode(TreeNode pRoot, int k)
{
if(pRoot==null || k==0)
return null;
this.k=k;
return KthNodeRec(pRoot);
}
TreeNode KthNodeRec(TreeNode pRoot){
TreeNode target=null;
if(pRoot.left!=null)
target=KthNode(pRoot.left,k);
if(target==null){
if(k==1)
return target=pRoot;
k--;
}
if(target==null && pRoot.right!=null)
target=KthNode(pRoot.right,k);
return target;
}
}


查找

2.1 题目(面试题18):树的子结构
解法一:前序遍历两个树,然后判断是否包含,空间复杂度是O(m+n);

import java.util.ArrayList;
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if((root1==null)||(root2==null))
return false;
ArrayList<Integer> array1=new ArrayList<Integer>();

ArrayList<Integer> array2=new ArrayList<Integer>();

array1=preOrder(root1);
array2=preOrder(root2);

if(array1.containsAll(array2))
return true;
return false;
}

private ArrayList<Integer> preOrder(TreeNode root){
if(root==null)
return null;
ArrayList<Integer> temp=new ArrayList<Integer>();
temp.add(root.val);
ArrayList<Integer> left=preOrder(root.left);
if(left!=null)
temp.addAll(left);
ArrayList<Integer> right=preOrder(root.right);
if(right!=null)
temp.addAll(right);
return temp;
}
}
解法二:递归解法,空间复杂度低

public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
boolean result=false;
if(root1!=null && root2!=null){
if(root1.val==root2.val){
result=DoTree1HasTree2(root1,root2);
}
if(!result){
result=HasSubtree(root1.left,root2);
}
if(!result){
result=HasSubtree(root1.right,root2);
}
}
return result;
}
private boolean DoTree1HasTree2(TreeNode root1,TreeNode root2){
if(root2==null){
return true;
}
if(root1==null)
return false;
if(root1.val!=root2.val){
return false;
}
return DoTree1HasTree2(root1.left,root2.left)&&DoTree1HasTree2(root1.right,root2.right);
}
}
2.2 题目(面试题19):二叉树的镜像

解法一:递归实现

public class Solution {
public void Mirror(TreeNode root) {
if(root==null)
return;
if(root.left==null && root.right==null)
return;
else {
TreeNode temp=root.right;
root.right=root.left;
root.left=temp;
Mirror(root.left);
Mirror(root.right);
}
}
}

相关题目:

题目1:对称二叉树,二叉树和它的镜像一样则为对称

public class Solution {
boolean isSymmetrical(TreeNode pRoot)
{
if(pRoot==null)
return true;
return rec(pRoot.left,pRoot.right);
}
private boolean rec(TreeNode left, TreeNode right){
if(left==null && right==null)
return true;
else if(left==null || right==null)
return false;
else if(left.val!=right.val)
return false;
return rec(left.right, right.left) && rec(left.left, right.right);
}
}


2.3 题目(面试题25):二叉树中和为某一值的路径

public class Solution {
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
ArrayList<ArrayList<Integer>> pathlist=new ArrayList<ArrayList<Integer>>();
if(root==null)
return pathlist;
Stack<Integer> stack=new Stack<Integer>();
FindPath(root,target,stack,pathlist);
return pathlist;
}

private void FindPath(TreeNode root,int target,Stack<Integer> path,ArrayList<ArrayList<Integer>> pathlist){
if(root==null)
return;
if(root.left==null && root.right==null){
if(root.val==target){
ArrayList<Integer> list= new ArrayList<Integer>();
for(int p:path){
list.add(new Integer(p));
}
list.add(new Integer(root.val));
pathlist.add(list);
}
}
else{
path.push(new Integer(root.val));
FindPath(root.left,target-root.val,path,pathlist);
FindPath(root.right,target-root.val,path,pathlist);
path.pop();
}
}
}

2.4 题目(面试题39):二叉树的深度,最长的路径

public class Solution {
public int TreeDepth(TreeNode root) {
if(root==null)
return 0;
TreeNode left=root.left;
TreeNode right=root.right;
return Math.max(1+TreeDepth(left),1+TreeDepth(right));
}
}
相关题目:

题目1:平衡二叉树

解法一:基于二叉树的深度递归解法;

解法二:基于后序遍历的解法;

2.5 题目(面试题50):最低公共祖先

2.6 题目(面试题27):二叉搜索树与双向链表

方法二:递归版
解题思路:
1.将左子树构造成双链表,并返回链表头节点。
2.定位至左子树双链表最后一个节点。
3.如果左子树链表不为空的话,将当前root追加到左子树链表。
4.将右子树构造成双链表,并返回链表头节点。
5.如果右子树链表不为空的话,将该链表追加到root节点之后。
6.根据左子树链表是否为空确定返回的节点。
public TreeNode Convert(TreeNode root) {
if(root==null)
return null;
if(root.left==null&&root.right==null)
return root;
// 1.将左子树构造成双链表,并返回链表头节点
TreeNode left = Convert(root.left);
TreeNode p = left;
// 2.定位至左子树双链表最后一个节点
while(p!=null&&p.right!=null){
p = p.right;
}
// 3.如果左子树链表不为空的话,将当前root追加到左子树链表
if(left!=null){
p.right = root;
root.left = p;
}
// 4.将右子树构造成双链表,并返回链表头节点
TreeNode right = Convert(root.right);
// 5.如果右子树链表不为空的话,将该链表追加到root节点之后
if(right!=null){
right.left = root;
root.right = right;
}
return left!=null?left:root;
}
方法三:改进递归版
解题思路:
思路与方法二中的递归版一致,仅对第2点中的定位作了修改,新增一个全局变量记录左子树的最后一个节点。
// 记录子树链表的最后一个节点,终结点只可能为只含左子树的非叶节点与叶节点
protected TreeNode leftLast = null;
public TreeNode Convert(TreeNode root) {
if(root==null)
return null;
if(root.left==null&&root.right==null){
leftLast = root;// 最后的一个节点可能为最右侧的叶节点
return root;
}
// 1.将左子树构造成双链表,并返回链表头节点
TreeNode left = Convert(root.left);
// 3.如果左子树链表不为空的话,将当前root追加到左子树链表
if(left!=null){
leftLast.right = root;
root.left = leftLast;
}
leftLast = root;// 当根节点只含左子树时,则该根节点为最后一个节点
// 4.将右子树构造成双链表,并返回链表头节点
TreeNode right = Convert(root.right);
// 5.如果右子树链表不为空的话,将该链表追加到root节点之后
if(right!=null){
right.left = root;
root.right = right;
}
return left!=null?left:root;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: