1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. If there isn't such day, output -1.
  6. Example 1:
  7. Input:
  8. flowers: [1,3,2]
  9. k: 1
  10. Output: 2
  11. Explanation: In the second day, the first and the third flower have become blooming.
  12. Example 2:
  13. Input:
  14. flowers: [1,2,3]
  15. k: 1
  16. Output: -1
  17. Note:
  18. The given array will be in the range [1, 20000].

解法一: 时间O(N * LogN) 空间 O(N)

思路: 对于任意一个位置i, 假设i开花了, i 需要看下左侧离它最近的开花位置是不是i - k - 1, 或者看下右侧离它最近的位置是不是i + k + 1,

所以是个搜索问题. 搜索的话,我们知道有上下界查找,在java中,查数A的上界即找第一个大于该数的值,下界即找最后一个小于该数的值, 前提是整个数有序

而在本题中,我们可以使用treeset保存开花位置,每输入一个新的位置,在TreeSet中找左侧离该位置最近的位置,或者右侧离该位置最近的位置,即查找上下界

判断距离上下界的距离是否为k,第一个满足条件的为结果

  1. class Solution {
  2. public int kEmptySlots(int[] flowers, int k) {
  3. TreeSet<Integer> tree = new TreeSet<>();
  4. int day = 0;
  5. for (int flower : flowers) {
  6. ++day;
  7. tree.add(flower);
  8. Integer lower = tree.lower(flower);
  9. if (lower != null && flower - lower - 1 == k) return day;
  10. Integer higher = tree.higher(flower);
  11. if (higher != null && higher - flower - 1 == k) return day;
  12. }
  13. return -1;
  14. }
  15. }

解法二: 时间O(N) 空间O(N)

思路: 维护每个位置开花的日期, 如果存在某个区间符合条件,那么需要满足a[left] < min(a[left + 1] ... a[left + k]) && a[right] < min(a[left + 1] ... a[left + k])

可以考虑维护这个区间内的最小值,用两端的值跟区间内最小值比较,难点是该如何维护这个数据结构?

a[left] 要么比区间内的最小值大,要么等于,要么小于

因为我们要维护区间内的最小值,区间内的淘汰规则应该是小的淘汰大的,

所以如果a[left]比区间内的最小值小,那么假设我们维护了最小值队列,那么a[left]应该在区间前面

如果a[left]比区间内最小值大,那么它不会出现在最小值队列中

假设我们维护两个队列,一个存原始数据, 一个存区间内的最小值

假设left = 0, 第一个区间的right 应该为 k + 1

在入队第k个元素后,我们构造了前k个数的最小队列, a[left] 可能在队列中,也可能不在

我们先从原始队列中弹出a[left], 然后如果a[left] == 最小值队列的头部元素值,则从最小值队列中也把该值弹出

然后比较 a[left] 与 最小值队列当前的队头值,然后比较a[right]和最小值队头值, 如果满足条件a[left] < min(a[left + 1] ... a[left + k]) && a[right] < min(a[left + 1] ... a[left + k])

则得到一个可能的结果,最终从这些结果中,挑值最小的即为最终解

  1. class Solution {
  2. public int kEmptySlots(int[] flowers, int k) {
  3. int[] days = new int[flowers.length];
  4. for (int i = 0; i < days.length; i++) {
  5. days[flowers[i] - 1] = i + 1;
  6. }
  7. int ans = Integer.MAX_VALUE;
  8. MinQueue<Integer> mins = new MinQueue<>();
  9. for (int i = 0; i < days.length; i++) {
  10. mins.addLast(days[i]);
  11. if (i >= k) {
  12. Integer x = mins.pollFirst();
  13. if (mins.isEmpty()) {
  14. if (i + 1 < days.length) {
  15. ans = Math.min(ans, Math.max(x, days[i + 1]));
  16. }
  17. } else {
  18. if (x < mins.min() && i + 1 < days.length && days[i + 1] < mins.min()) {
  19. ans = Math.min(ans, Math.max(x, days[i + 1]));
  20. }
  21. }
  22. }
  23. }
  24. if (ans == Integer.MAX_VALUE) {
  25. ans = -1;
  26. }
  27. return ans;
  28. }
  29. }
  30. class MinQueue<E extends Comparable<E>> extends ArrayDeque<E> {
  31. Deque<E> mins;
  32. public MinQueue() {
  33. mins = new ArrayDeque<E>();
  34. }
  35. @Override
  36. public void addLast(E x) {
  37. super.addLast(x);
  38. while (mins.peekLast() != null && x.compareTo(mins.peekLast()) < 0) {
  39. mins.pollLast();
  40. }
  41. mins.addLast(x);
  42. }
  43. @Override
  44. public E pollFirst() {
  45. E x = super.pollFirst();
  46. if (0 == x.compareTo(mins.peekFirst())) {
  47. mins.pollFirst();
  48. }
  49. return x;
  50. }
  51. public E min() {
  52. return mins.peekFirst();
  53. }
  54. }

解法三: 时间O(N) 空间O(N)

思路: 与解法二思路相同, 维护K + 2大小的区间, 假设有两个满足条件的区间

[k1, k2] 和 [k3, k4], 可以得到一个结论: 这两个区间不能重合

因为假设两区间重合 k1 < k3 < k2 < k4, 那么k3 和 k4 中间存在一个比它俩都小的值,则[k3, k4]不满足解的条件,与已知条件矛盾

所以不可能重合.

同时对于一个区间内,如果遇到一个位置p, p < k1 或者 p < k2, 那么p之前位置都不可能是解, 此时,我们从p开始重新查找可行解.

  1. class Solution {
  2. public int kEmptySlots(int[] flowers, int k) {
  3. int[] days = new int[flowers.length];
  4. for (int i = 0; i < days.length; i++) {
  5. days[flowers[i] - 1] = i + 1;
  6. }
  7. int left = 0, right = k + 1;
  8. int ans = Integer.MAX_VALUE;
  9. search:
  10. while (right < days.length) {
  11. for (int j = left + 1; j < right; j++) {
  12. if (days[j] < days[left] || days[j] < days[right]) {
  13. left = j;
  14. right = j + k + 1;
  15. continue search;
  16. }
  17. }
  18. ans = Math.min(ans, Math.max(days[left], days[right]));
  19. left = right;
  20. right = left + k + 1;
  21. }
  22. if (ans == Integer.MAX_VALUE) ans = -1;
  23. return ans;
  24. }
  25. }

解题报告-683. K Empty Slots的更多相关文章

  1. LC 683. K Empty Slots 【lock,hard】

    There is a garden with N slots. In each slot, there is a flower. The N flowers will bloom one by one ...

  2. [LeetCode] 683. K Empty Slots K个空槽

    There is a garden with N slots. In each slot, there is a flower. The N flowers will bloom one by one ...

  3. [LeetCode] K Empty Slots K个空槽

    There is a garden with N slots. In each slot, there is a flower. The N flowers will bloom one by one ...

  4. 【九度OJ】题目1174:查找第K小数 解题报告

    [九度OJ]题目1174:查找第K小数 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1174 题目描述: 查找一个数组的第 ...

  5. 【LeetCode】863. All Nodes Distance K in Binary Tree 解题报告(Python)

    [LeetCode]863. All Nodes Distance K in Binary Tree 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http ...

  6. 【剑指Offer】链表中倒数第k个节点 解题报告(Python)

    [剑指Offer]链表中倒数第k个节点 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://www.nowcoder.com/ta/coding-intervie ...

  7. 【LeetCode】402. Remove K Digits 解题报告(Python)

    [LeetCode]402. Remove K Digits 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http: ...

  8. 【LeetCode】373. Find K Pairs with Smallest Sums 解题报告(Python)

    [LeetCode]373. Find K Pairs with Smallest Sums 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/p ...

  9. 【LeetCode】692. Top K Frequent Words 解题报告(Python)

    [LeetCode]692. Top K Frequent Words 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/top ...

随机推荐

  1. [爬虫] 学Scrapy,顺便把它的官方教程给爬下来

    想学爬虫主要是因为算法和数据是密切相关的,有数据之后可以玩更多有意思的事情,数据量大可以挖掘挖掘到更多的信息. 之前只会通过python中的request库来下载网页内容,再用BeautifulSou ...

  2. 阿里历年经典Java面试题汇总

    Volatile的特征: A.禁止指令重排(有例外) B.可见性 Volatile的内存语义: 当写一个volatile变量时,JMM会把线程对应的本地内存中的共享变量值刷新到主内存. 当读一个vol ...

  3. Windows10解决无法访问其他机器共享的问题

    你不能访问此共享文件夹,因为你组织的安全策略阻止未经身份验证的来宾访问.这些策略可帮助保护你的电脑免受网络上不安全设备或恶意设备的威胁. 管理员身份执行sc.exe config lanmanwork ...

  4. 2018-2019-2 《网络对抗技术》Exp3免杀原理与实践 20165222

    1. 实践内容  1.1 正确使用msf编码器 使用 msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 7 -b ...

  5. MAC OX 配置 Tomcat 说明

    1: 首先在官网下载 Tomcat(我选择的是最新的9.0) , http://tomcat.apache.org/ 2:下载完成之后将压缩包解压在/Library/下 可使用快捷键 control+ ...

  6. MariaDB Galera Cluster的配置测试

    参考的https://fykuan.hsnuer.net/blog/2015/01/23/debian-%E4%B8%8A%E5%AE%89%E8%A3%9D-mariadb-galera-clust ...

  7. win7 php5.6 redis扩展

    步骤: 1.下载redis扩展 redis扩展下载地址:http://windows.php.net/downloads/pecl/snaps/redis/ 查看phpinfo下载匹配的版本(一定要选 ...

  8. Bootstrap的介绍和响应式媒体查询

    Bootstrap的介绍 凡是使用过Bootstrap的开发者,都不在乎做这么两件事情:复制and粘贴.哈哈~,是的使用Bootstrap非常简单,但是在复制粘贴之前,需要先对Bootstrap的用法 ...

  9. POI导出Excel和InputStream存储为文件

    POI导出Excel和InputStream存储为文件   本文需要说明的两个问题 InputStream如何保存到某个文件夹下 POI生成Excel POI操作utils类 代码如下.主要步骤如下: ...

  10. 1_boostrap概述

    1.bootstrap概述 1.1.什么是bootstrap?bootstrap的作用? Bootstrap,基于 HTML.CSS.JAVASCRIPT 的前端框架. 该框架已经预定义了一套CSS样 ...