-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
147 lines (129 loc) · 2.91 KB
/
main.go
File metadata and controls
147 lines (129 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Source: https://leetcode.com/problems/closest-binary-search-tree-value-ii
// Title: Closest Binary Search Tree Value II
// Difficulty: Hard
// Author: Mu Yang <http://muyang.pro>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Given the `root` of a binary search tree, a `target` value, and an integer `k`, return the `k` values in the BST that are closest to the `target`. You may return the answer in **any order**.
//
// You are **guaranteed** to have only one unique set of `k` values in the BST that are closest to the `target`.
//
// **Example 1:**
// https://assets.leetcode.com/uploads/2021/03/12/closest1-1-tree.jpg
//
// ```
// Input: root = [4,2,5,1,3], target = 3.714286, k = 2
// Output: [4,3]
// ```
//
// **Example 2:**
//
// ```
// Input: root = [1], target = 0.000000, k = 1
// Output: [1]
// ```
//
// **Constraints:**
//
// - The number of nodes in the tree is `n`.
// - `1 <= k <= n <= 10^4`.
// - `0 <= Node.val <= 10^9`
// - `-10^9 <= target <= 10^9`
//
// **Follow up:** Assume that the BST is balanced. Could you solve it in less than `O(n)` runtime (where `n = total nodes`)?
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package main
import (
"sort"
"github.com/emirpasic/gods/v2/trees/binaryheap"
)
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
// Use Heap
func closestKValues(root *TreeNode, target float64, k int) []int {
_abs := func(x float64) float64 {
if x < 0 {
return -x
}
return x
}
heap := binaryheap.NewWith(func(a, b int) int { // max heap
diff := _abs(target-float64(a)) - _abs(target-float64(b))
if diff > 0 {
return -1
}
if diff < 0 {
return 1
}
return 0
})
// DFS
var dfs func(node *TreeNode)
dfs = func(node *TreeNode) {
if node == nil {
return
}
heap.Push(node.Val)
if heap.Size() > k {
heap.Pop()
}
dfs(node.Left)
dfs(node.Right)
}
dfs(root)
return heap.Values()
}
// Convert tree to array
func closestKValues2(root *TreeNode, target float64, k int) []int {
_abs := func(x float64) float64 {
if x < 0 {
return -x
}
return x
}
// DFS
var nums []int
var dfs func(node *TreeNode)
dfs = func(node *TreeNode) {
if node == nil {
return
}
dfs(node.Left)
nums = append(nums, node.Val)
dfs(node.Right)
}
dfs(root)
// Find
n := len(nums)
idx := sort.Search(n, func(i int) bool {
return float64(nums[i]) >= target
})
// Answer
ans := make([]int, 0, k)
i, j := idx-1, idx
for range k {
if i < 0 {
ans = append(ans, nums[j])
j++
continue
}
if j >= n {
ans = append(ans, nums[i])
i--
continue
}
diffI := _abs(target - float64(nums[i]))
diffJ := _abs(target - float64(nums[j]))
if diffI < diffJ {
ans = append(ans, nums[i])
i--
} else {
ans = append(ans, nums[j])
j++
}
}
return ans
}