forked from DengWangBao/Leetcode-Java
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKEmptySlots.java
58 lines (52 loc) · 2.49 KB
/
KEmptySlots.java
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
import java.util.TreeSet;
/**
* 这题意思是第i盆花第flowers[i]天开,问第几天的时候存在这么一种情况:有两盆已经开的花中间恰好隔着k盆没开的花
*/
public class KEmptySlots {
public int kEmptySlots(int[] flowers, int k) {
TreeSet<Integer> map = new TreeSet<>();
for (int i = 0; i < flowers.length; i++) {
int flower = flowers[i] - 1;
map.add(flower);
Integer key = map.ceiling(flower + 1);
if (key != null && key - flower == k + 1) {
return i + 1;
}
key = map.floor(flower - 1);
if (key != null && flower - key == k + 1) {
return i + 1;
}
}
return -1;
}
/**
* 时间复杂度O(n)
* days表示第i盆花第几天开
* 天数越大,表示花开的越晚
* 对于(left, right)这个区间,(这个区间刚好相隔k),如果days值都比left和right大,说明(left,right)区间的花都开的比left和right晚
* 换言之,在left和right开的时候,中间的花都没开,而left和right刚好相隔k,符合条件。
* 我们选择left和right之中较大的那个值作为备选结果之一,选取较大是因为表示发生的较晚,刚好触发条件
* 但是题目要返回最早的那一天,所以我们要继续遍历下去
*
* 此外还要注意,当发现(left,right)区间存在不符合条件的情况,则sliding window要从i开始,因为如果从(left,i)区间的任何一个数开始,都不会符合条件
* 另外当找到一组符合条件的情况后,sliding window也要从i开始,也就是从right开始,假如从left+1开始,则当前的right就不符合大于sliding window两端的条件了
*/
public int kEmptySlots2(int[] flowers, int k) {
int[] days = new int[flowers.length];
for (int i = 0; i < flowers.length; i++) days[flowers[i] - 1] = i + 1;
int left = 0, right = k + 1, res = Integer.MAX_VALUE;
for (int i = left + 1; i <= right && right < days.length; i++) {
if (i == right) {
res = Math.min(res, Math.max(days[left], days[right]));
left = i;
right = k + 1 + i;
continue;
}
if (days[i] < days[left] || days[i] < days[right]) {
left = i;
right = k + 1 + i;
}
}
return (res == Integer.MAX_VALUE) ? -1 : res;
}
}