Description
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].
Solution
花园中有N个花池,每天都会有一株花开花然后保持开花状态。flowers数组记录的是第i天开花的花在花园中的位置。给一个k,要求找到在哪一天(多个情况下的最小天)时,正好有两个已经开花的花池,它俩中间有k个空的花池。
We want the day that two flowers have k empty slots between them. So make it a reverse, we use days array to contain the blooming day of the flower at position i. Now it becomes to a problem that we want to find a window with size k. The boundary left & right is the flower blooms at days[left] and days[right]. The flowers I between them have the properity that days[left + I] > days[left] && days[left + I] > days[right].
Based on that, we start iteration, it ends when rights reach the end of days. If days[I] < days[left] or <= days[right], if it is right, calculate a result. After that, update the postion of left and right.
Code
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;
int res = Integer.MAX_VALUE;
for (int i = 0; right < days.length; i++){
if (days[i] < days[left] || days[i] <= days[right]){
if (i == right){
res = Math.min(res, Math.max(days[left], days[right]));
}
left = i;
right = i + k + 1;
}
}
return res == Integer.MAX_VALUE ? -1 : res;
}
}
Time Complexity: O(n)
Space Complexity: O(n)
Review
A TLE solution which document new blooming flower position and then calculate empty slots one by one.
class Solution {
public int kEmptySlots(int[] flowers, int k) {
int len = flowers.length;
int[] slots = new int[len];
for (int i = 0; i < len; i++){
slots[flowers[i] - 1] = 1;
if (i < 1){
continue;
}
for (int j = 0; j < len; j++){
if (slots[j] == 1){
int nextFlower = j + 1;
while(nextFlower < len && slots[nextFlower] != 1){
nextFlower++;
}
if (nextFlower - j - 1 == k && nextFlower != len){
return i + 1;
}
}
}
}
return -1;
}
}