描述
牛牛从牛毕那里拿了一根长度为n的白木板,木板被等分成了n段(没有被切割,只是虚拟划分成了n段),其中有些段被牛毕用颜料染成了黑色。
牛牛非常不喜欢黑色,它找来了一桶清洗剂决定对木板进行清洗,但是牛牛发现自己的清洗剂最多只能清洗m段。
清洗完后,牛牛会把木板锯成纯色的几段。例如假设木板是 (黑黑黑白白白白黑黑黑 ),就会被锯成(黑黑黑)(白白白白)(黑黑黑)三段。
牛牛想知道,它足够聪明地清洗木板,能获得的纯白色木板的最大长度是多少。
示例1
输入:
6,1, [1,0,0,1,1,1]
返回值:
4
说明:
染成了[1,0,1,1,1,1]
示例2
输入:
6,2, [1,0,0,1,1,1]
返回值:
6
说明:
染成了[1,1,1,1,1,1]
备注:
给定n,m两个整数 和一个长度为n的数组a,为1表示白色,为0表示黑色 (1≤n≤10^6 , 1≤m≤n ) (0≤ai≤1)
解题思路:
-
首先统计出黑色区域的个数,即数组中0的个数。
-
如果黑色区域的个数小于等于m,则整个木板都可以清洗成白色。
-
如果黑色区域的个数大于m,则需要进行多次清洗。每次清洗将黑色区域分成两段,一段是左边最近的黑色区域,一段是右边最近的黑色区域。然后将这两段清洗成白色,直到黑色区域的个数小于等于m为止。
-
最后返回清洗后的纯白色木板的长度。
Java代码实现:
public int solve(int n, int m, int[] a) {
int blackCount = 0;
for (int i = 0; i < n; i++) {
if (a[i] == 0) {
blackCount++;
}
}
if (blackCount <= m) {
return n;
}
int left = 0, right = 0;
int count = 0;
while (right < n) {
while (right < n && count < m) {
if (a[right] == 0) {
count++;
}
right++;
}
if (count >= m) {
break;
}
while (left< right && count >= m) {
if (a[left] == 0) {
count--;
}
left++;
}
count = 0;
for (int i = left; i< right; i++) {
if (a[i] == 0) {
count++;
}
}
if (count >= m) {
right = left + 1;
count = 0;
}
}
return right;
}