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.

    本题还是比较难的,先说常规方法,首先把树分成两部分,一个是小于target的,一个是大于等于target的,然后进行比较,找出k个接近target的k个值,代码如下:

     1 /**
     2  * Definition for a binary tree node.
     3  * public class TreeNode {
     4  *     int val;
     5  *     TreeNode left;
     6  *     TreeNode right;
     7  *     TreeNode(int x) { val = x; }
     8  * }
     9  */
    10 public class Solution {
    11     public List<Integer> closestKValues(TreeNode root, double target, int k) {
    12         List<Integer> res = new ArrayList<Integer>();
    13         Stack<Integer> s1 = new Stack<Integer>();
    14         Stack<Integer> s2 = new Stack<Integer>();
    15         Inorder(s1,false,root,target);
    16         Inorder(s2,true,root,target);
    17         while(k-->0){
    18             if(s1.isEmpty()){
    19                 res.add(s2.pop());
    20             }else if(s2.isEmpty()){
    21                 res.add(s1.pop());
    22             }else if(Math.abs(s1.peek()-target)<Math.abs(s2.peek()-target)){
    23                 res.add(s1.pop());
    24             }else{
    25                 res.add(s2.pop());
    26             }
    27         }
    28         return res;
    29     }
    30     public void Inorder(Stack<Integer> s,boolean reverse,TreeNode root,double target){
    31         if(root==null) return;
    32         Inorder(s,reverse,reverse?root.left:root.right,target);
    33         if((reverse&&(root.val>target))||(!reverse&&(root.val<=target))) return;
    34         s.push(root.val);
    35         Inorder(s,reverse,reverse?root.right:root.left,target);
    36     }
    37 }

     然而此方法的时间复杂度并没有减少,时间复杂度为O(n+k),所以有了动态的优化方法:

    思路是,创建四个方法,分别有两个初始化,两个获取下一个方法。初始化的作用是找到target最近的较大和较小TreeNode,同时如果在过程中的也满足条件,把其放入stack中。获取下一个方法是,获取后,转其对应的另外子树,同时遍历一个h,代码如下:

     1 /**
     2  * Definition for a binary tree node.
     3  * public class TreeNode {
     4  *     int val;
     5  *     TreeNode left;
     6  *     TreeNode right;
     7  *     TreeNode(int x) { val = x; }
     8  * }
     9  */
    10 public class Solution {
    11     public List<Integer> closestKValues(TreeNode root, double target, int k) {
    12         List<Integer> res = new ArrayList<Integer>();
    13         Stack<TreeNode> succ = new Stack<TreeNode>();
    14         Stack<TreeNode> pre = new Stack<TreeNode>();
    15         initalizesucc(root,target,succ);
    16         initalizepre(root,target,pre);
    17         if(!succ.isEmpty()&&!pre.isEmpty()&&succ.peek().val==pre.peek().val){
    18             getNextpre(pre);
    19         }
    20         while(k-->0){
    21             if(succ.isEmpty()){
    22                res.add(getNextpre(pre)); 
    23             }else if(pre.isEmpty()){
    24                 res.add(getNextsucc(succ));
    25             }else{
    26                 double succ_diff = Math.abs((double)succ.peek().val-target);
    27                 double pre_diff = Math.abs((double)pre.peek().val-target);
    28                 if(succ_diff<pre_diff){
    29                     res.add(getNextsucc(succ));
    30                 }else{
    31                     res.add(getNextpre(pre));
    32                 }
    33             }
    34         }
    35         return res;
    36     }
    37     public void initalizesucc(TreeNode root,double target,Stack<TreeNode> succ){
    38         while(root!=null){
    39             if(root.val==target){
    40                 succ.push(root);
    41                 break;
    42             }else if(root.val<target){
    43                 root = root.right;
    44             }else{
    45                 succ.push(root);
    46                 root = root.left;
    47             }
    48         }
    49     }
    50     public void initalizepre(TreeNode root,double target,Stack<TreeNode> pre){
    51         while(root!=null){
    52             if(root.val==target){
    53                 pre.push(root);
    54                 break;
    55             }else if(root.val<target){
    56                 pre.push(root);
    57                 root = root.right;
    58             }else{
    59                 root = root.left;
    60             }
    61         }
    62     }
    63     public int getNextsucc(Stack<TreeNode> stack){
    64         TreeNode succ = stack.pop();
    65         int val = succ.val;
    66         succ = succ.right;
    67         while(succ!=null){
    68             stack.push(succ);
    69             succ = succ.left;
    70         }
    71         return val;
    72     }
    73     public int getNextpre(Stack<TreeNode> stack){
    74         TreeNode pre = stack.pop();
    75         int val = pre.val;
    76         pre = pre.left;
    77         while(pre!=null){
    78             stack.push(pre);
    79             pre = pre.right;
    80         }
    81         return val;
    82     }
    83 }
  • 相关阅读:
    [RxSwift]3.3、数据绑定(订阅)
    [RxSwift]3.2、函数式编程 -> 函数响应式编程
    [RxSwift]2、Hello RxSwift!:我的第一个 RxSwift 应用程序
    [RxSwift]1、为什么要使用 RxSwift ?
    [RxSwift]RxSwift: ReactiveX for Swift
    [Swift]UIViewController
    104. 二叉树的最大深度
    103. 二叉树的锯齿形层次遍历
    102. 二叉树的层序遍历
    98. 验证二叉搜索树
  • 原文地址:https://www.cnblogs.com/codeskiller/p/6608214.html
Copyright © 2011-2022 走看看