Algorithm: Binary Tree(2) -- Special Trees (BST and Balanced Tree)

来源:互联网 发布:l800清零维修软件 编辑:程序博客网 时间:2024/05/21 07:16

判断一棵二叉树是否是平衡二叉树


类似问题:判断一棵树是否是二叉搜索树 (98. Validate Binary Search Tree)


总体思路:平衡二叉树(左右子树的高度相差最多1):每个根节点,如果左子树是平衡的,且右子树是平衡的,而且两者高度相差小于1,则到current node是平衡二叉树。这里有个trick,用了返回高度的办法,如果是-1的话证明其中一棵子树不是平衡的。如果是大于0则是正常的子树高度。通过分治,得到答案:


public class Solution {      /**      * @param root: The root of binary tree.      * @return: True if this Binary tree is Balanced, or false.      */      private int maxDepth(TreeNode input){          if(input == null){              return 0;          }          int temp1 = maxDepth(input.left);          int temp2 = maxDepth(input.right);                    if(temp1 == -1 || temp2 == -1 || Math.abs(temp1-temp2)>1)              return -1;          else{              return 1+Math.max(temp1,temp2);          }      }                  public boolean isBalanced(TreeNode root) {          // write your code here          return maxDepth(root) != -1;      }  }  


二叉搜索树(左子树的所有值小于根,右子树的所有值大于根):因为是要求所有值,所以不能像上题一样,直接判断当前的左右点是否一个比current node大,一个比current node小。那么,就要换过来,用遍历的每个点都检查自己是否比最大值小,比最小值大(位置决定你的范围)。如果是的话,继续递归下去让自己的孩子们检查,否则直接返回false.


public class Solution {      private boolean lookFromCur(TreeNode cur, int max, int min) {          if (cur == null) {              return true;          }                    //look from the current node, I should not bigger than max or smaller than min          if (cur.val >= max || cur.val <= min) {              return false;          }          return (lookFromCur(cur.left, cur.val, min) && lookFromCur(cur.right, max, cur.val));      }            public boolean isValidBST(TreeNode root) {          return lookFromCur(root, Integer.MAX_VALUE, Integer.MIN_VALUE);      }  }  


对于BST,二叉搜索树,题目是离不开其利于大小构造性质、中序遍历有序的性质。


对应的题目有:


501. Find Mode in Binary Search Tree

270. Closest Binary Search Tree Value

255. Verify Preorder Sequence in Binary Search Tree

235. Lowest Common Ancestor of a Binary Search Tree

173. Binary Search Tree Iterator

108. Convert Sorted Array to Binary Search Tree

109. Convert Sorted List to Binary Search Tree

99. Recover Binary Search Tree


501. Find Mode in Binary Search Tree


利用中序遍历的顺序,查看在中序中连成一串的数字个数。prev是记录(root.left)完的那个root. 


public class Solution {    private TreeNode prev = null;    private ArrayList<Integer> ans = new ArrayList<Integer>();    private int count = 0;    private int countMax = 0;        private void traversal(TreeNode root) {        if (root == null) {            return;        }                traversal(root.left);        if (prev != null && prev.val == root.val) {            count = count + 1;        } else {            count = 1;        }                if (count > countMax) {            countMax = count;            ans.clear();            ans.add(root.val);        } else if (count == countMax) {            ans.add(root.val);        }        prev = root;        traversal(root.right);    }        public int[] findMode(TreeNode root) {        traversal(root);        int[] res = new int[ans.size()];        for (int i = 0; i < res.length; i++) {              res[i] = ans.get(i);          }                    return res;     }}


270. Closest Binary Search Tree Value


Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target.


Note:
Given target value is a floating point.
You are guaranteed to have only one unique value in the BST that is closest to the target.


public class Solution {    private Integer ans = null;    private double minDiff = Double.MAX_VALUE;        public int closestValue(TreeNode root, double target) {        // 一个全局答案,然后根据目标大小调整向下的前进方向        if (root == null) {            return ans;        }                TreeNode cur = root;        double tmpDiff = 0;                while (cur != null) {            tmpDiff = Math.abs(cur.val - target);            if (tmpDiff < minDiff) {                minDiff = tmpDiff;                ans = cur.val;            }                        if (cur.val < target) {                cur = cur.right;            } else {                cur = cur.left;            }        }        return ans;    }}




272. Closest Binary Search Tree Value II
Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target.


Note:
Given target value is a floating point.
You may assume k is always valid, that is: k ≤ total nodes.
You are guaranteed to have only one unique set of k values in the BST that are closest to the target.


Hint:


Consider implement these two helper functions:
getPredecessor(N), which returns the next smaller node to N.
getSuccessor(N), which returns the next larger node to N.
Try to assume that each node has a parent pointer, it makes the problem much easier.




255 Verify Preorder Sequence in Binary Search Tree


Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary search tree.


You may assume each number in the sequence is unique.


Follow up:
Could you do it using only constant space complexity?


public class Solution {    private boolean recursion(int[] preorder, int start, int end) {        if (start >= end) {            return true; // only one node        }        int firstBigger = -1;        int pivot = preorder[start];//每次dereference会增加损耗,这题体现了                for (int i = start + 1; i <= end; i++) {            if (firstBigger == -1 && preorder[i] > pivot) {                firstBigger = i;            }            if (firstBigger != -1 && preorder[i] < pivot) {//如果大的那边还有小,就可以直接返回false了                return false;            }        }                if (firstBigger == -1) {            // 斜树            return recursion(preorder, start + 1, end);        }        return (recursion(preorder, start + 1, firstBigger - 1) && recursion(preorder, firstBigger, end));    }            public boolean verifyPreorder(int[] preorder) {        if (preorder == null || preorder.length == 0) {            return true;        }        return recursion(preorder, 0, preorder.length - 1);    }}


235. Lowest Common Ancestor of a Binary Search Tree


Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.


According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”


        _______6______
       /              \
    ___2__          ___8__
   /      \        /      \
   0      _4       7       9
         /  \
         3   5
For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.


173. Binary Search Tree Iterator


Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.


Calling next() will return the next smallest number in the BST.


Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.


public class Solution {    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {        // 一个比它大,一个比它小,或者其中一个就是root        if (root.val >= p.val && root.val <= q.val) {            return root;        }        if (root.val <= p.val && root.val >= q.val) {            return root;        }                if (root.val < p.val && root.val < q.val) {            return lowestCommonAncestor(root.right, p, q);        }                if (root.val > p.val && root.val > q.val) {            return lowestCommonAncestor(root.left, p, q);        }                return null;    }}



108. Convert Sorted Array to Binary Search Tree


Given an array where elements are sorted in ascending order, convert it to a height balanced BST.


public class Solution {    public TreeNode sortedArrayToBST(int[] nums) {        if (nums == null || nums.length == 0) {            return null;        }        return recursion(nums, 0, nums.length - 1);    }        private TreeNode recursion(int[] nums, int start, int end) {        if (start > end) {//注意这个终止条件            return null;        }        int mid = start + ((end - start) / 2);        TreeNode cur = new TreeNode(nums[mid]);        cur.left = recursion(nums, start, mid - 1);        cur.right = recursion(nums, mid + 1, end);        return cur;    }}


109. Convert Sorted List to Binary Search Tree


Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.


public class Solution {    private TreeNode recursion(ListNode head, ListNode end) {        if (head == end) {            return null;        }        ListNode fast = head.next;        ListNode slow = head;                while (fast != end && fast.next != end) {            fast = fast.next.next;            slow = slow.next;        }                TreeNode cur = new TreeNode(slow.val);        cur.left = recursion(head, slow);//注意这里是slow,不是prev之类的        cur.right = recursion(slow.next, end);        return cur;    }        public TreeNode sortedListToBST(ListNode head) {        return recursion(head, null);    }}



99. Recover Binary Search Tree


Two elements of a binary search tree (BST) are swapped by mistake.


Recover the tree without changing its structure.


Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?


public class Solution {    public void recoverTree(TreeNode root) {        if (root == null || (root.left == null && root.right == null)) {            return;           }                LinkedList<TreeNode> stack = new LinkedList<TreeNode>();        TreeNode cur = root;        TreeNode pre = null;        TreeNode first = null;        TreeNode second = null;                while (cur != null || !stack.isEmpty()) {            while (cur != null) {                stack.addFirst(cur);                cur = cur.left;            }                        cur = stack.removeFirst();            if (pre != null) {                if (pre.val > cur.val) {                    if (first == null) {                        first = pre;                    }                    second = cur; // 注意这部分的逻辑,精妙                }            }            pre = cur;            cur = cur.right;        }                if (first == null) {            return;        }                //swap two nodes' value        int tmp = first.val;        first.val = second.val;        second.val = tmp;    }}



0 0