[LeetCode] K Empty Slots K个空槽
You have N bulbs in a row numbered from 1 to N. Initially, all the bulbs are turned off. We turn on exactly one bulb everyday until all bulbs are on after N days.
You are given an array bulbs of length N where bulbs[i] = x means that on the (i+1)th day, we will turn on the bulb at position x where i is 0-indexed and x is 1-indexed.
Given an integer K, find out the minimum day number such that there exists two turned on bulbs that have exactly K bulbs between them that are all turned off.
If there isn't such day, return -1.
Example 1:
Input:
bulbs: [1,3,2]
K: 1
Output: 2
Explanation:
On the first day: bulbs[0] = 1, first bulb is turned on: [1,0,0]
On the second day: bulbs[1] = 3, third bulb is turned on: [1,0,1]
On the third day: bulbs[2] = 2, second bulb is turned on: [1,1,1]
We return 2 because on the second day, there were two on bulbs with one off bulb between them.
Example 2:
Input:
bulbs: [1,2,3]
K: 1
Output: -1
Note:
1 <= N <= 200001 <= bulbs[i] <= Nbulbsis a permutation of numbers from1toN.0 <= K <= 20000
这道题给了我们这样一个场景,说是花园里有N个空槽,可以放花,每天放一朵开着的花,而且一旦放了就会一直开下去。不是按顺序放花,而是给了我们一个数组 flowers,其中 flowers[i] = x 表示第i天放的花会在位置x。其实题目这里有误,数组是从0开始的,而天数和位置都是从1开始的,所以正确的应该是第 i+1 天放的花会在位置x。然后给了我们一个整数k,让我们判断是否正好有两朵盛开的花中间有k个空槽,如果有,返回当前天数,否则返回-1。博主刚开始想的是先用暴力破解来做,用一个状态数组,如果该位置有花为1,无花为0,然后每增加一朵花,就遍历一下状态数组,找有没有连续k个0,结果TLE了。这说明,应该等所有花都放好了,再来找才行,但是这样仅用0和1的状态数组是不行的,我们得换个形式。
我们用一个 days 数组,其中 days[i] = t 表示在 i+1 位置上会在第t天放上花,那么如果 days 数组为 [1 3 2],就表示第一个位置会在第一天放上花,第二个位置在第三天放上花,第三个位置在第二天放上花。我们想,在之前的状态数组中,0表示没放花,1表示放了花,而 days 数组中的数字表示放花的天数,那么就是说数字大的就是花放的时间晚,那么在当前时间i,所有大于i的是不是也就是可以看作是没放花呢,这样问题就迎刃而解了,我们来找一个 k+2 大小的子数组,除了首尾两个数字,中间的k个数字都要大于首尾两个数字即可,那么首尾两个数字中较大的数就是当前的天数。left 和 right 是这个大小为 k+2 的窗口,初始化时 left 为0,right 为 k+1,然后i从0开始遍历,这里循环的条件时 right 小于n,当窗口的右边界越界后,循环自然需要停止。如果当 days[i] 小于 days[left],或者 days[i] 小于等于 days[right] 的时候,有两种情况,一种是i在[left, right]范围内,说明窗口中有数字小于边界数字,这不满足我们之前限定的条件,至于days[i]为何可以等于 days[right],是因为当i遍历到 right 到位置时,说明中间的数字都是大于左右边界数的,此时我们要用左右边界中较大的那个数字更新结果 res。不管i是否等于 right,只要进了这个if条件,说明当前窗口要么是不合题意,要么是遍历完了,我们此时要重新给 left 和 right 赋值,其中 left 赋值为i,right 赋值为 k+1+i,还是大小为 k+2 的窗口,继续检测。最后我们看结果 res,如果还是 INT_MAX,说明无法找到,返回 -1 即可,参见代码如下:
解法一:
class Solution {
public:
int kEmptySlots(vector<int>& flowers, int k) {
int res = INT_MAX, left = , right = k + , n = flowers.size();
vector<int> days(n, );
for (int i = ; i < n; ++i) days[flowers[i] - ] = i + ;
for (int i = ; right < n; ++i) {
if (days[i] < days[left] || days[i] <= days[right]) {
if (i == right) res = min(res, max(days[left], days[right]));
left = i;
right = k + + i;
}
}
return (res == INT_MAX) ? - : res;
}
};
下面这种方法用到了 TreeSet 来做,利用其自动排序的特点,然后用 lower_bound 和 upper_bound 进行快速的二分查找。 题目中的 flowers[i] = x 表示第 i+1 天放的花会在位置x。所以我们遍历 flowers 数组,其实就是按照时间顺序进行的,我们取出当前需要放置的位置 cur,然后在集合 TreeSet 中查找第一个大于 cur 的数字,如果存在的话,说明两者中间点位置都没有放花,而如果中间正好有k个空位的话,那么当前天数就即为所求。这是当 cur 为左边界的情况,同样,我们可以把 cur 当右边界来检测,在集合 TreeSet 中查找第一个小于 cur 的数字,如果二者中间有k个空位,也返回当前天数。需要注意的是,C++ 和 Java 中的 upper_bound 和 higher 是相同作用的,但是 lower_bound 和 lower 却不太一样。C++ 中的 lower_bound 找的是第一个不小于目标值的数字,所以可能会返回和目标值相同或者大于目标值的数字。只要这个数字不是第一个数字,然后我们往前退一位,就是要求的第一个小于目标值的数字,这相当于 Java 中的 lower 函数,参见代码如下:
解法二:
class Solution {
public:
int kEmptySlots(vector<int>& flowers, int k) {
set<int> s;
for (int i = ; i < flowers.size(); ++i) {
int cur = flowers[i];
auto it = s.upper_bound(cur);
if (it != s.end() && *it - cur == k + ) {
return i + ;
}
it = s.lower_bound(cur);
if (it != s.begin() && cur - *(--it) == k + ) {
return i + ;
}
s.insert(cur);
}
return -;
}
};
讨论:这道题有一个很好的 follow up,就是改为最后的有k盆连续开花的是哪一天,就是k个连续不空的槽,博主没有想出特别好的解法,只能采用暴力搜索的解法。比如就像解法一,求出了 days 数组后。我们可以遍历每个长度为k的子数组,然后找出该子数组中最大的数字,然后找出所有的这些最大数字中的最小的一个,就是所求。或者,我们可以使用类似于合并区间的思想,遍历 flowers 数组,每遍历一个数字,如果跟现有的区间连续,就加入当前区间,直到出现某个区间的长度大于等于k了,则当前天数即为所求。如果各位看官大神们有更好的解法,一定要留言告知博主哈~
Github 同步地址:
https://github.com/grandyang/leetcode/issues/683
参考资料:
https://leetcode.com/problems/k-empty-slots/
https://leetcode.com/problems/k-empty-slots/discuss/107931/JavaC%2B%2B-Simple-O(n)-solution
https://leetcode.com/problems/k-empty-slots/discuss/107960/C%2B%2B-ordered-set-Easy-solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] K Empty Slots K个空槽的更多相关文章
- [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 ...
- 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 ...
- 解题报告-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 ...
- [LeetCode] All Nodes Distance K in Binary Tree 二叉树距离为K的所有结点
We are given a binary tree (with root node root), a target node, and an integer value K. Return a li ...
- 乘风破浪:LeetCode真题_023_Merge k Sorted Lists
乘风破浪:LeetCode真题_023_Merge k Sorted Lists 一.前言 上次我们学过了合并两个链表,这次我们要合并N个链表要怎么做呢,最先想到的就是转换成2个链表合并的问题,然后解 ...
- [LeetCode] 358. Rearrange String k Distance Apart 按距离k间隔重排字符串
Given a non-empty string str and an integer k, rearrange the string such that the same characters ar ...
- 求和问题总结(leetcode 2Sum, 3Sum, 4Sum, K Sum)
转自 http://tech-wonderland.net/blog/summary-of-ksum-problems.html 前言: 做过leetcode的人都知道, 里面有2sum, 3sum ...
- Leetcode 992 Subarrays with K Different Integers
题目链接:https://leetcode.com/problems/subarrays-with-k-different-integers/ 题意:已知一个全为正数的数组A,1<=A.leng ...
- [leetcode]692. Top K Frequent Words K个最常见单词
Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted b ...
随机推荐
- 第一次使用github、git工具,本地仓库、远程仓库使用
一次使用git,记录下使用过程...可能还有很多东西可能还没理解,后期理解了再写吧 git是什么.,百度的回答: 一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 使用过程一直在百度 ...
- Oracle查询优化改写--------------------操作多个表
一.union all与空字符串 二.组合相关行 三.in .exists.inter join .left join .right join .full join 之间的区别 'inner joi ...
- 关于js中promise的面试题。
核心点promise在生命周期内有三种状态,分别是pending,fulfilled或rejected,状体改变只能是 pending-fulfilled,或者pending-rejected.而且状 ...
- CSS速查列表-2-(text)文本
CSS的Text属性可以改变页面中 1.文本的颜色(color). 2.字符间距(word-spacing ) 属性可以改变字(单词)之间的标准间隔.其默认值 normal 与设置值为 0 是一样的 ...
- Vue 知识复习(上)
Vue Vue实例 创建实例: var vm = new Vue({ //code }) 数据与方法: 只有当实例被创建时 data 中存在的属性才是响应式的; Vm.b = 'h1' 是不会触发视图 ...
- 关于使用Mybatis的使用说明(一)【未完善待更新】
(一)搭建Mybatis环境 (1)先导入常用的jar包:并且需要将lib文件夹下的包导入到项目中 (2)创建config文件夹,配置log4j.properties文件 # Global loggi ...
- Beta冲刺NO.5
Beta冲刺 第五天 1. 昨天的困难 1.昨天的困难主要是在类的整理上,一些逻辑理不清,也有一些类写的太绝对了,扩展性就不那么好了,所以,昨天的困难就是在重构上. 页面结构太凌乱,之前没有统筹好具体 ...
- 20162318 实验二《Java面向对象程序设计》实验报告
北京电子科技学院(BESTI) 实 验 报 告 课程:程序设计与数据结构 班级:1623班 姓名:张泰毓 指导老师:娄老师.王老师 实验日期:2017年4月14日 实验密级:非密级 实验器材:带Lin ...
- 项目Alpha冲刺Day7
一.会议照片 二.项目进展 1.今日安排 今天都是课,主要就是用空闲时间熟悉一下框架使用以及继续进行框架搭建. 2.问题困难 前台界面框架vue和element-ui的写法要适应. 3.心得体会 vu ...
- iOS开发-OC分支结构
BOOL类型 返回值:真:YES 假:NO BOOL数据类型占一个字节的内存空间,占位符为%d. 计算机在识别时,YES就替换成1,NO就替换成0. bool是C语言中的布尔类型,返回值为true ...