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].
class Solution {
public int kEmptySlots(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, result = Integer.MAX_VALUE;
for (int i = 0; right < days.length; i++) {
if (days[i] < days[left] || days[i] <= days[right]) {
if (i == right)
result = Math.min(result, Math.max(days[left], days[right]));
left = i;
right = k + 1 + i;
}
}
return (result == Integer.MAX_VALUE) ? -1 : result;
}
}
public int kEmptySlots(int[] flowers, int k) {
int n = flowers.length;
if (n == 1 && k == 0) return 1;
TreeSet sort = new TreeSet<>();
for (int i = 0; i < n; ++i) {
sort.add(flowers[i]);
Integer min = sort.lower(flowers[i]);
Integer max = sort.higher(flowers[i]);
if (min != null && flowers[i] - min == k + 1) return i + 1;
if (max != null && max - flowers[i] == k + 1) return i + 1;
}
return -1;
}
public int kEmptySlots(int[] flowers, int k) {
if (flowers.length == 0) return -1;
HashSet set = new HashSet<>();
for (int i = 0; i < flowers.length; i++) {
set.add(flowers[i]);
int pre = flowers[i] - k - 1, next = flowers[i] + k + 1, tag = 0;
if (pre >= 1 && set.contains(pre)) {
for (int j = pre + 1; j < pre + 1 + k; j++) {
if (set.contains(j)) {
tag = 1;
break;
}
}
if (tag == 0) return i + 1;
}
tag = 0;
if (next <= flowers.length && set.contains(next)) {
for (int j = flowers[i] + 1; j < next; j++) {
while (set.contains(j)) {
tag = 1;
break;
}
}
if (tag == 0) return i + 1;
}
}
return -1;
}
解题思路:
树状数组(Fenwick Tree)
树状数组ft[k]存储前k个槽一共有多少朵花,则区间[m, n]的花朵总数 = ft[n] - ft[m - 1]
利用该数据结构,遍历flowers即可求解。
Python代码:
class Solution(object):
def kEmptySlots(self, flowers, k):
"""
:type flowers: List[int]
:type k: int
:rtype: int
"""
maxn = max(flowers)
nums = [0] * (maxn + 1)
ft = FenwickTree(maxn)
for i, v in enumerate(flowers):
ft.add(v, 1)
nums[v] = 1
if v >= k and ft.sum(v) - ft.sum(v - k - 2) == 2 and nums[v - k - 1]:
return i + 1
if v + k + 1<= maxn and ft.sum(v + k + 1) - ft.sum(v - 1) == 2 and nums[v + k + 1]:
return i + 1
return -1