剑指offer 树

来源:互联网 发布:java执行cmd命令 参数 编辑:程序博客网 时间:2024/05/17 22:28

二叉树

完全二叉树

二叉搜索树

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;             }  


0 0
原创粉丝点击