leedcode-二叉树

(代码粘贴过来没有缩进=-=!手动添加的缩进,缩进可能有误)

基本方法
  • 由数组构造二叉树(null 用 0 表示)
  • 先序,中序,后序,层次遍历(递归,迭代)
  • 深度
public class TreeNode{
	 public int val;
	 public TreeNode left;
	 public TreeNode right;
	 public TreeNode(int x){
		  val = x;
	 }
 }
  1. 构建二叉树
    public TreeNode createBinaryTree(int[] array, int index){
     
	     TreeNode node = null;
	     if(index < array.length) {
		      if(array[index] != 0) {
                              node = new TreeNode(array[index]);
                      }else {
                              return node;
                      }
       		      node.left = createBinaryTree(array, 2*index+1);
        	      node.right = createBinaryTree(array, 2*index+2);  
             }
	     return node;
    }
  1. 先序遍历
    public void preOrderTraversal(TreeNode root) {
	     if(root == null) {
		      return;
	     }
     
	     System.out.print(root.val + " ");
	     preOrderTraversal(root.left);
	     preOrderTraversal(root.right);
    }
    public void preOrderTraversal1(TreeNode root) {
     
	     Stack<TreeNode> stack = new Stack<>();
	     TreeNode node = root;
     
	     while(node != null || !stack.isEmpty()) {
		      while(node != null) {
			       System.out.print(node.val + " ");
			       stack.add(node);
			       node = node.left;
		      }
		      node = stack.pop();
		      node = node.right;
	     }
    }
  1. 中序遍历
    public void inOrderTraversal(TreeNode root) {
	     if(root == null) {
		      return;
	     }
     
	     inOrderTraversal(root.left);
	     System.out.print(root.val + " ");
	     inOrderTraversal(root.right);
    }
    public void inOrderTraversal1(TreeNode root) {
     
	     Stack<TreeNode> stack = new Stack<>();
	     TreeNode node = root;
     
	     while(node != null || !stack.isEmpty()) {
		      while(node != null) {       
			       stack.add(node);
			       node = node.left;
		      }
		     node = stack.pop();
	  	     System.out.print(node.val + " ");
		     node = node.right;
	     }
    }
  1. 后序遍历
    public void postOrderTraversal(TreeNode root) {
	     if(root == null) {
		      return;
	     }
     
	     postOrderTraversal(root.left);
	     postOrderTraversal(root.right);
	     System.out.print(root.val + " ");
    }
    
    public void postOrderTraversal1(TreeNode root) {
     
	     Stack<TreeNode> stack = new Stack<>();
     
	     TreeNode node = root;
	     // 记录上一个visit节点
	     TreeNode lastVisit = root;
     
	     while(node != null || !stack.isEmpty()) {
      
		      while(node != null) {
			       stack.add(node);
			       node = node.left;
		      }
      
		      node = stack.peek();
      
		      // 如果右节点为null 或者  右节点为上一次访问过的节点   访问该节点
		      if(node.right == null || node.right == lastVisit) {
			       System.out.print(node.val + " ");
			       lastVisit = node;
			       stack.pop();
			       node = null;
		      }else {
			       node = node.right;
		      } 
	     }
    }
  1. 层次遍历
    public void levelOrderTraversal(TreeNode root) {
     
	     if(root == null) {
		      return;
	     }
	     Queue<TreeNode> queue = new LinkedList<>();
     
	     TreeNode node = root;
	     queue.add(node);
     
	     while(!queue.isEmpty()) {
		   node = queue.poll();
		   System.out.print(node.val + " ");
		   if(node.left != null) {
			    queue.add(node.left);
		   }
	           if(node.right != null) {
		            queue.add(node.right);
	           }
	     }    
    }
    // 记录每层数据
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
	     if(root == null) {
		      return new ArrayList<>();
	     }
	     List<List<Integer>> ans = new ArrayList<>();
     
	     Queue<TreeNode> queue = new LinkedList<>();
     
	     TreeNode node = root;
	     queue.add(node);
     
	     while(!queue.isEmpty()) {
		      List<Integer> level = new ArrayList<>();
		      int len = queue.size();
		      for(int i = 0; i < len; i++) {
			       node = queue.poll();
			       level.add(node.val);
			       if(node.left != null) {
			       		queue.add(node.left);
		               }
		               if(node.right != null) {
			                queue.add(node.right);
		               }
		      }
		      System.out.println(Arrays.toString(level.toArray()));
		      ans.add(0, level);
	     }
	     return ans;
    } 
  1. 树的深度
    public int depth(TreeNode root) {
	     if(root == null) {
		      return 0;
	     }
	     int left = depth(root.left);
	     int right = depth(root.right);
     
	     return Math.max(left, right) + 1;
    }
leedcode
  • 二叉搜索树相关问题
  • 中序遍历与前/后序遍历构造二叉树
  • 树的深度问题(平衡二叉树,最小深度)
  • 路径问题(根到叶子路径和,最大路径和等)
  1. 二叉搜索树
   /*
    * 95 不同的二叉搜索树
    * 给定一个整数 n,生成所有由 1 ... n 为节点所组成的二叉搜索树
    * */
    public List<TreeNode> generateTrees(int n) {
     
	     if(n == 0) {
		      return new ArrayList<>();
	     }
     
	     return help(1, n);
    }
    public List<TreeNode> help(int start, int end){
	     List<TreeNode> allTree = new ArrayList<>();
     
	     // 添加null值
	     if(start > end) {
		      allTree.add(null);
		      return allTree;
	     }
     
	     for(int i = start; i <= end; i++) {
		      // 以i为根节点的左右子树
		      List<TreeNode> left = help(start, i-1);
		      List<TreeNode> right = help(i+1, end);
      
		      // 左右子树笛卡尔积
		      for(TreeNode lnode : left) {
			       for(TreeNode rnode : right) {
				        TreeNode node = new TreeNode(i);
				        node.left = lnode;
				        node.right = rnode;
				        allTree.add(node);
			       }
		      }
	     }
     
	     return allTree;
    } 
    /*
     * 96 不同的二叉搜索树个数
     * G(n): 长度为n的序列的不同二叉搜索树个数    G(0) = G(1) = 1
     * F(i, n): 以i为根的不同二叉搜索树的个数
     * F(i, n) = G(i-1) * G(n-i)
    * */
    public int numTrees(int n) {
     
	     int[] g = new int[n+1];
	     g[0] = 1;
	     g[1] = 1;
     
	     for(int i = 2; i <= n; i++) {
		      for(int j = 1; j <= i; j++) {
			      g[i] += g[j-1] * g [i-j];
		      }
	     }
     
	     return g[n];
    }    
    /*
     * 98 验证二叉搜索树
     * 采取中序遍历
     * */
    public boolean isValidBST(TreeNode root) {
     
	     Stack<TreeNode> stack = new Stack<>();
     
	     TreeNode node = root;
	     double last = -Double.MAX_VALUE;
     
	     while(node != null || !stack.isEmpty()) {
      
		      while(node != null) {
			       stack.add(node);
			       node = node.left;
		      }
      
		      node = stack.pop();
		      // 不允许有重复值
		      if(node.val <= last) {
			       return false;
		      }
		      last = node.val;
		      node = node.right;
	     }
	     return true;
    }
    /*
     * 99 恢复二叉搜索树
     *  二叉搜索树中的两个节点被错误地交换,请在不改变其结构的情况下,恢复这棵树。
     *  通过中序遍历
     * */
    public void recoverTree(TreeNode root) {
        
	     Stack<TreeNode> stack = new Stack<>();
     
	     TreeNode node = root;
     
	     // 记录交换的节点和上一次的节点
	     TreeNode x = null;
	     TreeNode y = null;
	     TreeNode last = null;
    
	     while(node != null || !stack.isEmpty()) {
      
		      while(node != null) {
			       stack.push(node);
			       node = node.left;
		      }
      
		      node = stack.pop();
      
		      // 在一个交换x y的有序数组中寻找x y 
		      if(last != null && node.val < last.val) {
			       y = node;
			       if(x == null) {
				        x = last;
			       }else {
				        break;
			       }
		      }
		      last = node;
		      node = node.right;
	     }
     
	     // swap x.val y.val
	     int temp = x.val;
	     x.val = y.val;
	     y.val = temp;
    }
    /*
     * 108 将有序数组转换为平衡二叉搜索树
     * 从中间开始构建
     * */
    public int[] nums; 
    public TreeNode sortedArrayToBST(int[] nums) {
	     this.nums = nums;
     
	     return sortedArrayToBSTHelp(0, nums.length-1);
    }
    public TreeNode sortedArrayToBSTHelp(int start, int end) {
	     if(start > end) {
		      return null;
	     }
     
	     int index = (start + end) / 2;
     
	     TreeNode node = new TreeNode(nums[index]);
	     node.left = sortedArrayToBSTHelp(start, index-1);
	     node.right = sortedArrayToBSTHelp(index+1, end);
	     return node;
    }                      
  1. 前序与中序,中序与后序构造二叉树
    /*
     * 105 前序与中序遍历序列构造二叉树
     * 树中没有重复的元素
     * */
    private int[] preorder;
    private int[] inorder;
    // 保存inorder的index
    private HashMap<Integer, Integer> map = new HashMap<>();
    // 遍历preorder
    private int preIndex = 0;
    
    public TreeNode buildTree(int[] preorder, int[] inorder) {
     
	     this.preorder = preorder;
	     this.inorder = inorder;
     
	     for(int i = 0; i < inorder.length; i++) {
		      map.put(inorder[i], i);
 	    }
     
	     return buildTreeHelp(0, inorder.length);
    }
    public TreeNode buildTreeHelp(int start, int end) {
     
	     if(start == end) {
		      return null;
	     }
     
	     TreeNode node = new TreeNode(preorder[preIndex]);
     
	     int inIndex = map.get(preorder[preIndex]);
     
	     preIndex++;
     
	     node.left = buildTreeHelp(start, inIndex);
	     node.right = buildTreeHelp(inIndex + 1, end);
     
	     return node;
    }
    
    /*
     * 106 后序与中序遍历序列构造二叉树
     * 树中没有重复的元素
     * */
    private int[] postorder;
    private int[] inorder;
    // 保存postorder的index
    private HashMap<Integer, Integer> map = new HashMap<>();
    // 遍历preorder
    private int postIndex;
    
    public TreeNode buildTree(int[] inorder, int[] postorder) {
     
	      this.postorder = postorder;
	      this.inorder = inorder;
     	      this.postIndex = postorder.length - 1;
	      for(int i = 0; i < inorder.length; i++) {
		        map.put(inorder[i], i);
	      }
     
	      return buildTreeHelp(0, inorder.length);
    }
    public TreeNode buildTreeHelp(int start, int end) {
     
	      if(start == end) {
		        return null;
	      }
     
	      TreeNode node = new TreeNode(postorder[postIndex]);
     
	      int inIndex = map.get(postorder[postIndex]);
     
	      postIndex--;
     	  
	      node.right = buildTreeHelp(inIndex + 1, end);
	      node.left = buildTreeHelp(start, inIndex);
	      return node;
    }    
  1. 比较
    /*
     * 100 相同的树
     * */
    public boolean isSameTree(TreeNode p, TreeNode q) {
	     if(p == null && q == null) {
		      return true;
	     }
	     if(p == null || q == null) {
		      return false;
	     }
	     if(p.val != q.val) {
		      return false;
	     }
	     boolean left = isSameTree(p.left, q.left);
	     boolean right = isSameTree(p.right, q.right);
     
	     return left && right;
    }
    /*
     * 101 对称二叉树
     * */
    public boolean isSymmetric(TreeNode root) {
     
	     return isSymmetricHelp(root, root);
    }
    public boolean isSymmetricHelp(TreeNode p, TreeNode q) {
     
	     if(p == null && q == null) {
		      return true;
	     }
	     if(p == null || q == null) {
		      return false;
	     }
	     if(p.val != q.val) {
		      return false;
	     }
	     boolean l = isSymmetricHelp(p.left, q.right);
	     boolean r = isSymmetricHelp(p.right, q.left);
	     return l && r;
    }
  1. 树的深度
   /*
     * 110 平衡二叉树
     * */
    public int depth(TreeNode root) {
	     if(root == null) {
		      return 0;
	     }
	     int left = depth(root.left);
	     int right = depth(root.right);
     
	     return Math.max(left, right) + 1;
    }
    public boolean isBalanced(TreeNode root) {
     
	     if(root == null) {
		      return true;
	     }
	     return Math.abs(depth(root.left) - depth(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
    }
    /*
     * 111 最小深度
     * */
    public int minDepth(TreeNode root) {
	     if(root == null) {
		      return 0;
	     }
	     if(root.left == null && root.right == null){
		      return 1;
	     }
     
	     int min = Integer.MAX_VALUE;
	     if(root.left != null) {
		      min = Math.min(min, minDepth(root.left));
	     }
	     if(root.right != null) {
		      min = Math.min(min, minDepth(root.right));
	     }
     
	     return min + 1;
    }
  1. 路径问题
    /*
     * 112 路径总和是否存在
     * 递归  迭代
     * */
    public boolean hasPathSum(TreeNode root, int sum) {
	      if(root == null) {
		      return false;
	     }
	     sum -= root.val;
	     if(root.left == null && root.right == null) {
		      return sum == 0;
	     }
	     return hasPathSum(root.left, sum) || hasPathSum(root.right, sum);
    }
    
    public boolean hasPathSum1(TreeNode root, int sum) {
     
	     if(root == null) {
		      return false;
	     }
     
	     Stack<TreeNode> nodeStack = new Stack<>();
	     // sum-node.val
	     Stack<Integer> sumStack = new Stack<>() ;
     
	     TreeNode node = root;
     
	     nodeStack.add(node);
	     sumStack.add(sum - node.val);
     
	     while(!nodeStack.isEmpty()) {
      
		      node = nodeStack.pop();
		      int currentSum = sumStack.pop();
      
		      if(node.left == null && node.right == null && currentSum == 0) {
			       return true;
		      }
      
		      // 栈 : 先右后左
		      if(node.right != null) {
			       nodeStack.add(node.right);
			       sumStack.add(currentSum - node.right.val);
		      }
		      if(node.left != null) {
			       nodeStack.add(node.left);
			       sumStack.add(currentSum - node.left.val);
		      }
	     }
     
	     return false;
    }
    /*
     * 113 路径总和
     * */
    
    private List<List<Integer>> ans = new ArrayList<>();
    private List<Integer> temp = new ArrayList<>();
    public List<List<Integer>> pathSum(TreeNode root, int sum) {        
	     if(root == null) {
		      return new ArrayList<>();
	     }
	     temp.add(root.val);
	     sum -= root.val;
     
	     if(root.left == null && root.right == null && sum == 0) {
		      // 必须有new ArrayList<>(): 如果没有,会随着temp的改变而改变
		      ans.add(new ArrayList<>(temp));
	     }
	     pathSum(root.left, sum);
	     pathSum(root.right, sum);
     
	     temp.remove(temp.size() - 1);
	     return ans;
    }
    /*
     * 124 二叉树中最大的路径和
     * */
    private int max = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {    
	     maxPathSumHelp(root);
	     return max; 
    }
    public int maxPathSumHelp(TreeNode root) {
     
	     if(root == null) {
		      return 0;
	     }
	     
	     // 当左右树的和小于0时,截断
	     int left = Math.max(maxPathSumHelp(root.left), 0);
	     int right = Math.max(maxPathSumHelp(root.right), 0);
     
	     // 以当前节点为根节点的和
	     int newPath = left + right + root.val;
     
	     max = Math.max(max, newPath);
	     System.out.println(max);
	     // 返回当前节点为根的最大值
	     return Math.max(left, right) + root.val;
    }
    /*
     * 129 根到叶子节点数字之和
     * 1-2-3: 123
     * */
    private int onePath;
    private int allPath;
    public int sumNumbers(TreeNode root) {    
	     if(root == null) {
		      return 0;
	     }
	     onePath = onePath * 10 + root.val;
	     if(root.left == null && root.right == null) {
		      allPath += onePath;
	     }
	     sumNumbers(root.left);
	     sumNumbers(root.right);
     
	     onePath /= 10;
	     return allPath;
    }                                                                                  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值