-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
141 lines (128 loc) · 3.39 KB
/
main.go
File metadata and controls
141 lines (128 loc) · 3.39 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
// Source: https://leetcode.com/problems/k-empty-slots
// Title: K Empty Slots
// Difficulty: Hard
// Author: Mu Yang <http://muyang.pro>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// You have `n` bulbs in a row numbered from `1` to `n`. Initially, all the bulbs are turned off. We turn on **exactly one** bulb every day until all bulbs are on after `n` days.
//
// You are given an array `bulbs`of length `n`where `bulbs[i] = x` means that on the `(i+1)^th` day, we will turn on the bulb at position `x`where`i`is**0-indexed**and`x`is**1-indexed.**
//
// Given an integer `k`, return the **minimum day number** such that there exists two **turned on** bulbs that have **exactly**`k` bulbs between them that are **all turned off**. If there isn't such day, return `-1`.
//
// **Example 1:**
//
// ```
// Input: bulbs = [1,3,2], k = 1
// Output: 2
// Explanation:
// On the first day: bulbs[0] = 1, first bulb is turned on: [1,0,0]
// On the second day: bulbs[1] = 3, third bulb is turned on: [1,0,1]
// On the third day: bulbs[2] = 2, second bulb is turned on: [1,1,1]
// We return 2 because on the second day, there were two on bulbs with one off bulb between them.```
//
// **Example 2:**
//
// ```
// Input: bulbs = [1,2,3], k = 1
// Output: -1
// ```
//
// **Constraints:**
//
// - `n == bulbs.length`
// - `1 <= n <= 2 * 10^4`
// - `1 <= bulbs[i] <= n`
// - `bulbs`is a permutation of numbers from`1`to`n`.
// - `0 <= k <= 2 * 10^4`
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package main
import (
"github.com/emirpasic/gods/v2/trees/redblacktree"
)
// Brute-force
func kEmptySlots(bulbs []int, k int) int {
n := len(bulbs)
on := make([]bool, n+1)
checkLeft := func(curr int) bool {
left := curr - k - 1
if left < 1 {
return false
}
if !on[left] {
return false
}
for i := left + 1; i < curr; i++ {
if on[i] {
return false
}
}
return true
}
checkRight := func(curr int) bool {
right := curr + k + 1
if right > n {
return false
}
if !on[right] {
return false
}
for i := curr + 1; i < right; i++ {
if on[i] {
return false
}
}
return true
}
for day, bulb := range bulbs {
on[bulb] = true
if checkLeft(bulb) || checkRight(bulb) {
return day + 1
}
}
return -1
}
// Use tree
func kEmptySlots2(bulbs []int, k int) int {
type void struct{}
tree := redblacktree.New[int, void]()
for day, bulb := range bulbs {
tree.Put(bulb, void{})
if left, ok := tree.Floor(bulb - 1); ok && (bulb-left.Key-1 == k) {
return day + 1
}
if right, ok := tree.Ceiling(bulb + 1); ok && (right.Key-bulb-1 == k) {
return day + 1
}
}
return -1
}
// Track the day that bulb turns on
// Let days[b] = d be the time that `b`-th bulb turns on.
func kEmptySlots3(bulbs []int, k int) int {
n := len(bulbs)
days := make([]int, n) // bulb -> day
for day, bulb := range bulbs {
days[bulb-1] = day + 1
}
// Check if everything between days[bulb] and days[bulb+k+1] are larger
check := func(bulb int, day int) bool {
for j := bulb + 1; j <= bulb+k; j++ {
if days[j] < day {
return false
}
}
return true
}
ans := n + 1
for bulb := range n - k - 1 {
day := max(days[bulb], days[bulb+k+1])
if check(bulb, day) {
ans = min(ans, day)
}
}
if ans == n+1 {
return -1
}
return ans
}