LeetCode 题解(250) : 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.
题解:

正向Inorder + 反向Inorder。正向得到小于target的元素的顺序, 反向得到大于等于target的顺序,存于堆栈中,如target = 5.5,

正向栈得:12345,反向栈得9876,栈顶元素分别为5和6,以此比较两个栈的栈顶,加入结果中只到K个。

C++版:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> closestKValues(TreeNode* root, double target, int k) {
        vector<int> results;
        stack<int> incr, decr;
        inOrder(root, target, false, incr);
        inOrder(root, target, true, decr);
        while(results.size() < k) {
            if(incr.empty()) {
                results.push_back(decr.top());
                decr.pop();
            } else if (decr.empty()) {
                results.push_back(incr.top());
                incr.pop();
            } else if(abs(incr.top() - target) < abs(decr.top() - target)) {
                results.push_back(incr.top());
                incr.pop();
            } else {
                results.push_back(decr.top());
                decr.pop();
            }
        }
        return results;
    }
    
    void inOrder(TreeNode* root, double target, bool reverse, stack<int> &order) {
        if(root == NULL)
            return;
        inOrder(reverse ? root->right : root->left, target, reverse, order);
        if((reverse && root->val <= target) || (!reverse && root->val > target))
            return;
        order.push(root->val);
        inOrder(reverse ? root->left : root->right, target, reverse, order);
    }
};

Java版:

/**
 * 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) {
        List<Integer> results = new ArrayList<>();
        Stack<Integer> incr = new Stack<>();
        Stack<Integer> decr = new Stack<>();
        inOrder(root, target, false, incr);
        inOrder(root, target, true, decr);
        while(k != 0) {
            if(incr.empty()) {
                results.add(decr.pop());
            } else if (decr.empty()) {
                results.add(incr.pop());
            } else if(Math.abs(incr.peek() - target) > Math.abs(decr.peek() - target)) {
                results.add(decr.pop());
            } else {
                results.add(incr.pop());
            }
            k--;
        }
        return results;
    }
    
    void inOrder(TreeNode root, double target, boolean reverse, Stack<Integer> order) {
        if(root == null)
            return;
        inOrder(reverse ? root.right : root.left, target, reverse, order);
        if((reverse && root.val <= target) || (!reverse && root.val > target))
            return;
        order.push(root.val);
        inOrder(reverse ? root.left : root.right, target, reverse, order);
    }
}

Python版:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def closestKValues(self, root, target, k):
        """
        :type root: TreeNode
        :type target: float
        :type k: int
        :rtype: List[int]
        """
        incr, decr = [], []
        self.inOrder(root, target, False, incr)
        self.inOrder(root, target, True, decr)
        results = []
        while len(results) < k:
            if len(incr) == 0:
                results.append(decr.pop())
            elif len(decr) == 0:
                results.append(incr.pop())
            elif abs(incr[-1] - target) < abs(decr[-1] - target):
                results.append(incr.pop())
            else:
                results.append(decr.pop())
        return results
                
    def inOrder(self, root, target, reverse, order):
        if root == None:
            return
        if reverse:
            self.inOrder(root.right, target, reverse, order)
        else:
            self.inOrder(root.left, target, reverse, order)
        if (reverse and root.val < target) or (not reverse and root.val >= target):
            return
        order.append(root.val)
        if reverse:
            self.inOrder(root.left, target, reverse, order)
        else:
            self.inOrder(root.right, target, reverse, order)
        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值