LeetCode 683. 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: 212345

Explanation: In the second day, the first and the third flower have become blooming.

Example 2:
Input: 
flowers: [1,2,3]
k: 1
Output: -112345

Note:
The given array will be in the range [1, 20000].

思路1:

  1. 用treemap – 内部排序的hashmap,时间复杂度是O(nlogn),空间复杂度是O(n)。思路是遍历数组,每次都将花槽编号放进treeset,同时每次都检查到这天为止离此花槽编号最近的花槽编号,如果两个编号之间刚好相差k,那么就返回这时的天数。
  2. treeset.add() 将加入的元素自然排序;
    treeset.lower():返回集合中位于指定元素之前的元素(即小于指定元素的最大元素,参考元素不需要是TreeSet里面的元素);
    treeset.higher():返回集合中位于指定元素之后的元素,(即大于指定元素的最小元素,参考元素不需要是TreeSet的元素) ;

代码:

public class Treeset683 {
    public int kEmptySlots(int[] flowers, int k) {
        int n = flowers.length;
        if (n == 1 && k == 0) {
        	return 1;
        	}
        TreeSet<Integer> 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;
    }

思路2:

  1. 额外定义一个数组days,用来表示每朵花的开花时间,例如days[i] = y表示在位置i上的花的开花时间是第y天。那么问题就转化为:给定days数组之后,找出一个子区间[left, left + 1, …left + k - 1, right),满足对于任意的i = left + 1,…left + k - 1,满足days[left] < days[i] && days[right] < days[i]。如果找到了,就返回true,否则就返回false。
  2. 时间复杂度为O(n),空间复杂度为O(n)。

代码2:

public class Treeset683 {
    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;
    }
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值