2021.05.09.LeetCode每日一题1482
又是图书馆摸鱼的一天
题目描述:
个人题解及感想
- 二分查找
- 滑动窗口
滑动窗口: 对于某个特定的
d
a
y
day
day利用一个长度为
k
k
k的窗口,从左向右扫描,找到到符合条件的连续区域的最多的数量,如果这个数量满足全部的花,则返回day的值,否则返回-1。
二分查找: 观察本题的测试样例返回可知,当bloomDay
数组中的元组较大,或者查找的
d
a
y
day
day的值比较小,判断函数会多次返回False
,会损耗较多的时间,尤其是给定的1 <= bloomDay[i] <= 10^9
,如果采用顺序查找的方式,当
d
a
y
day
day较小时会造成大量的时间损耗。于是从
(
b
l
o
o
m
D
a
y
m
i
n
,
b
l
o
o
o
m
D
a
y
m
a
x
)
(bloomDay_{min},blooomDay_{max})
(bloomDaymin,blooomDaymax)区间采用二分查找的方式降低时间复杂度。
代码如下:
class Solution {
public:
int func(vector<int>& bloomDay, int m, int k, int day)
{
int flower = 0;
int left = 0;//设置窗口的左右界
int right = left + k;
while (right <= bloomDay.size())
{
bool judge = true;
int stop_pos = 0;
for (int i = left; i < right; i++)
{
if (bloomDay[i] > day)
{//如果中间有花不能采摘
judge = false;
stop_pos = i;
break;
}
}
if (judge)//表示可以取花
{
flower++;
left = right;
}
else//中间有花不能采摘
left = stop_pos + 1;
right = left + k;
if (flower == m)
return day;
}
return -1;
}
int minDays(vector<int>& bloomDay, int m, int k) {
if (m * k > bloomDay.size())
return -1;
int left = *(min_element(bloomDay.begin(), bloomDay.end()));
int right = *(max_element(bloomDay.begin(), bloomDay.end()));
while (left < right)
{
int mid = (left + right) >> 1;
int result = func(bloomDay, m, k, mid);
if (result != -1)
right = mid;
else
left = mid + 1;
}
return left;
}
};
func()
对当前的
d
a
y
day
day进行判断,二分查找的主体在minDays()
中
仅供学习参考,复习交流