1. 程式人生 > >LC 272. Closest Binary Search Tree Value II

LC 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.

Example:

Input: root = [4,2,5,1,3], target = 3.714286, and k = 2

    4
   / \
  2   5
 / \
1   3

Output: [4,3]

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

 

又是隻會暴力求解的我T T。

最簡單的一個思路就是遞迴帶一個order map,key是差值,value是一個vector,把所有差值存起來。最後遍歷一邊,因為一定是隻有K個解,所以只要遍歷到結果陣列中元素是K個就停。

遞迴的時間是O(n),遍歷的時間也是O(n)

Runtime 20ms  Beats: 5.34%

 

當然存在更好的解法啦。

題目說小於o(n),那一定有o(logn)的解法,想想也是,如果這不是一顆樹,是一個數組應該怎麼找呢,首先用lowerbound找到這個值,然後向兩邊擴散依此加入K個。

那如果是一顆樹,應該也是可以這麼做的,過程稍微複雜一點,參考了

StefanPochmann大神的帖子。Stefan大神每一個帖子都能讓我有重生的感覺(這程式碼是人寫出來的??),真的很佩服他。

在此先截一張圖,看一看大家對Stefan的敬仰

 

哈哈哈哈

好了言歸正傳,先把程式碼放上來

 

基本思路就是,首先我們找到一條通往與target最近的一個path,記錄下所有節點,然後向兩邊延申。

難點在於,樹怎麼延伸?其實問題轉化為,在一個二叉搜尋樹中給定一個節點,怎麼求比他大的第一個節點和比他小的第一個節點。

求比他大的第一個節點

分類討論,如果這個節點存在右子節點,那麼比他大的第一個節點就是右子節點的最左節點,否則,不斷的回溯之前的路徑,直到前一個節點

不是當前節點的右子節點(而是他的左子節點),因為噹噹前節點和路徑的前一個節點是父節點和左子節點的關係時才會存在父節點大於原來路徑中的節點的情況。

求比他小的就呼之欲出了

stefan沒有重新寫一遍,而是用了兩個lambda函式,交換了一下位置,就把意思反過來了。

之後就是不斷的更新即可。

整個過程,尋找path o(log(n)),向兩邊沿申最壞情況也是O(log(n))因為題目已經說了是平衡二叉樹。

下面給出我的實現。

 

 

另一種解法是中序遍歷,然後利用兩個雙端佇列,小於k的存一個,大於k的存另一個,然後從兩邊展開,這個思路好像更容易一點,而且竟然時間更快,

理論上因為有中序遍歷,這個時間複雜度是O(n)的。