-
Notifications
You must be signed in to change notification settings - Fork 154
/
k-empty-slots.js
141 lines (116 loc) · 3.13 KB
/
k-empty-slots.js
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
/**
* K Empty Slots
*
* There is a garden with N slots. In each slot, there is a flower.
* The N flowers will bloom one by one in N days.
* In each day, there will be exactly one flower blooming and it will be in the status of blooming since then.
*
* Given an array flowers consists of number from 1 to N.
* Each number in the array represents the place where the flower will open in that day.
*
* For example, flowers[i] = x means that the unique flower that blooms at day i will be at position x,
* where i and x will be in the range from 1 to N.
*
* Also given an integer k, you need to output in which day there exists two flowers in the status of blooming,
* and also the number of flowers between them is k and these flowers are not blooming.
*
* If there isn't such day, output -1.
*
* Example 1:
* Input:
* flowers: [1,3,2]
* k: 1
* Output: 2
* Explanation: In the second day, the first and the third flower have become blooming.
*
* Example 2:
* Input:
* flowers: [1,2,3]
* k: 1
* Output: -1
*
* Note:
* The given array will be in the range [1, 20000].
*/
/**
* @param {number[]} flowers
* @param {number} k
* @return {number}
*/
const kEmptySlots = (flowers, k) => {
const n = flowers.length;
const window = [];
const days = [];
for (let i = 0; i < n; i++) {
days[flowers[i] - 1] = i + 1;
}
let result = n;
for (let i = 0; i < n; i++) {
// Step 1. Remove the old item from window
if (window.length > 0 && window[0] === i - k) {
window.shift();
}
// Step 2. Try to pop the larger/smaller items
while (window.length > 0 && days[i] < days[window[window.length - 1]]) {
window.pop();
}
// Step 3. Push the new item, now window[0] holds the smallest/largest item
window.push(i);
// Step 4. Check the minimum day in the window with the left and right borders
if (i < k || i === n - 1) {
continue;
}
if (k === 0 || (days[i - k] < days[window[0]] && days[i + 1] < days[window[0]])) {
result = Math.min(result, Math.max(days[i - k], days[i + 1]));
}
}
return result < n ? result : -1;
};
/**
* @param {number[]} flowers
* @param {number} k
* @return {number}
*/
const kEmptySlotsII = (flowers, k) => {
const n = flowers.length;
const window = new MinQueue();
const days = [];
for (let i = 0; i < n; i++) {
days[flowers[i] - 1] = i + 1;
}
let result = n;
for (let i = 0; i < n; i++) {
window.push(days[i]);
if (k <= i && i < n - 1) {
window.shift();
if (k == 0 || (days[i - k] < window.min() && days[i + 1] < window.min())) {
result = Math.min(result, Math.max(days[i - k], days[i + 1]));
}
}
}
return result < n ? result : -1;
};
class MinQueue extends Array {
constructor() {
super();
this.mins = [];
}
push(x) {
super.push(x);
while (this.mins.length > 0 && x < this.mins[this.mins.length - 1]) {
this.mins.pop();
}
this.mins.push(x);
}
shift() {
const x = super.shift();
if (x == this.mins[0]) {
this.mins.shift();
}
return x;
}
min() {
return this.mins[0];
}
}
export { kEmptySlots, kEmptySlotsII };