zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    正反向代理工具squid
    docker安装jira
    pandas输出的数据集导入数据库
    python监控接口告警模板
    Auth认证
    Form与ModelForm的 使用
    原生Ajax与jQuery的Ajax和伪Ajax
    Django缓存与信号
    Django的生命周期与中间件的流程
    CSRF的原理和基本使用
  • 原文地址:https://www.cnblogs.com/yrbbest/p/5031304.html
Copyright © 2011-2022 走看看