1、题目描述
2、解题思路
题目给的 flowers[] 索引是第几天,值是花盆,天数从 0 开始,花盆从 1 开始。
我们把它转为 days[] ,索引是花盆,值是第几天,花盆从 0 开始,天数从 1 开始。
于是,我们可以使用滑动窗口的思路,来找到目标。
初始时,left = 0,right = k + 1;循环以下操作:
1、判断 [left+1, right-1] 是不是所有元素的值都小于 days[left] 和 days[right];
2、如果是,说明 left 花盆和 right 花盆盛开的时候,中间 k 盆花都是没开放的,满足题意要求,记录 targetDay = Math.max(days[left], days[right]),即至少最晚那个时间到了,才满足要求;
3、如果存在 i 是大于 days[left] 或 days[right],则不满足题意,开始滑动窗口,更新左右指针为:left = i,right = i + k + 1,重复步骤 1。
遍历完所有窗口,统计所有的 targetDay,如果一个 targetDay 都没有,说明不存在。否则返回 targetDay 中最小的那个,即最早就满足题意要求的那天。
扫描二维码关注公众号,回复:
11697692 查看本文章
3、解题代码
class Solution {
public int kEmptySlots(int[] flowers, int k) {
int[] days = new int[flowers.length];
for (int i = 0; i < flowers.length; i++) {
// days[2] = x 表示第 2 盆花在 x 天盛开
days[flowers[i] - 1] = i + 1;
}
int ans = Integer.MAX_VALUE; // 哪一天恰好有两朵盛开的花,他们中间间隔了 k 朵花并且都没有开放。
int left = 0, right = k + 1; // 初始滑动窗口
search:
while (right < days.length) {
for (int i = left + 1; i <= right - 1; i++) {
// 满足任意条件,说明当前窗口不满足题意,得滑动窗口
if (days[i] < days[left] || days[i] < days[right]) {
left = i;
right = i + k + 1;
continue search;
}
}
ans = Math.min(ans, Math.max(days[left], days[right]));
left = right;
right = left + k + 1;
}
return ans < Integer.MAX_VALUE ? ans : -1;
}
}