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.

 

Follow up:
Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)?

Hint:

    1. Consider implement these two helper functions:
      1. getPredecessor(N), which returns the next smaller node to N.
      2. getSuccessor(N), which returns the next larger node to N.
    2. Try to assume that each node has a parent pointer, it makes the problem much easier.
    3. Without parent pointer we just need to keep track of the path from the root to the current node using a stack.
    4. You would need two stacks to track the path in finding predecessor and successor node separately.

鏈接:  http://leetcode.com/problems/closest-binary-search-tree-value-ii/

題解:

一開始思路非常不明確,看了不少discuss也不明白為什么。在午飯時間從頭仔細想了一下,像Closest Binary Search Tree Value I一樣,追求O(logn)的解法可能比較困難,但O(n)的解法應該不難實現。我們可以使用in-order的原理,從最左邊的元素開始,維護一個Deque或者doubly linked list,將這個元素的值從后端加入到Deque中,然后繼續遍歷下一個元素。當Deque的大小為k時, 比較當前元素和隊首元素與target的差來嘗試更新deque。循環結束條件是隊首元素與target的差更小或者遍歷完全部元素。這樣的話時間復雜度是O(n), 空間復雜度應該是O(k)。

Time Complexity - O(n), Space Complexity - O(k)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> closestKValues(TreeNode root, double target, int k) {
        LinkedList<Integer> res = new LinkedList<>();
        inOrder(root, target, k, res);
        return res;
    }
    
    private void inOrder(TreeNode root, double target, int k, LinkedList<Integer> res) {
        if(root == null) {
            return;
        }
        inOrder(root.left, target, k, res);
        if(res.size() == k) {
            if(Math.abs(res.get(0) - target) >= Math.abs(root.val - target)) {
                res.removeFirst();
                res.add(root.val);
            } else {
                return;
            }
        } else {
            res.add(root.val);
        }
        inOrder(root.right, target, k, res);
    }
}

 

二刷:

還是使用inorder traversal來遍歷樹,同時維護一個size為k的LinkedList或者Deque。這個原理類似於sliding window。

Java:

Time Complexity - O(n), Space Complexity - O(k)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> closestKValues(TreeNode root, double target, int k) {
        LinkedList<Integer> res = new LinkedList<>();
        inOrderTraversal(root, target, k, res);
        return res;
    }
    
    private void inOrderTraversal(TreeNode root, double target, int k, LinkedList<Integer> res) {
        if (root == null) {
            return;
        }
        inOrderTraversal(root.left, target, k, res);
        if (res.size() < k) {
            res.add(root.val);
        } else if(res.size() == k) {
            if (Math.abs(res.getFirst() - target) > (Math.abs(root.val - target))) {
                res.removeFirst();
                res.addLast(root.val);
            } else {
                return;
            }
        }
        inOrderTraversal(root.right, target, k, res);
    }
}

 

 

Reference:

https://leetcode.com/discuss/55261/efficient-python

https://leetcode.com/discuss/70577/java-in-order-traversal-1ms-solution

https://leetcode.com/discuss/64713/clear-java-solution-with-one-stack-one-linkedlist

https://leetcode.com/discuss/64713/clear-java-solution-with-one-stack-one-linkedlist

https://leetcode.com/discuss/69220/2-ms-o-n-and-6-ms-o-logn-java-solution

https://leetcode.com/discuss/55240/ac-clean-java-solution-using-two-stacks

https://leetcode.com/discuss/55682/o-logn-java-solution-with-two-stacks-following-hint

https://leetcode.com/discuss/55486/java-two-stacks-iterative-solution

https://leetcode.com/discuss/64713/clear-java-solution-with-one-stack-one-linkedlist

https://leetcode.com/discuss/71820/java-5ms-iterative-following-hint-o-klogn-time-and-space

https://leetcode.com/discuss/70577/java-in-order-traversal-1ms-solution


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM