超时版本1:
基本思路为:先排序,将所有的左边填充到一个辅助数组中,最后遍历这个数组。
class Solution {
public:
int maximumWhiteTiles(vector<vector<int>>& tiles, int carpetLen) {
// 排序
sort(begin(tiles), end(tiles), [](auto &ele1, auto &ele2){return ele1[0] <= ele2[0];});
int ans = 0;
// 声明辅助数组,长度为最大的坐标值(该值太大时,这里会出现内存申请溢出),默认值填充为0
vector<int> aux(tiles[tiles.size() - 1][1] + 1,0);
// 遍历所有的白色坐标范围,标记aux
for(int i = 0; i < tiles.size(); i++){
for(int j = tiles[i][0]; j <= tiles[i][1]; j++){
aux[j] = 1;
}
}
int subAns = 0;
int i = 0;
// 先计算出第一个可以覆盖白色数量
for(; i < carpetLen && i < aux.size(); i++){
if(aux[i] == 1){
subAns++;
}
}
ans = subAns;
// 如果实际的坐标范围小于,0到carpetLen, 则直接返回结果
if(i < carpetLen){
return ans;
}
// 继续向下遍历
for(; i < aux.size(); i++){
// 是否增加白色数量
bool incr = false;
// 如果当前(即将进入范围的)为白色,则累加结果
if(aux[i] == 1){
subAns++;
incr = true;
}
// 如果即将移除范围的坐标,为白色,则累减
if(aux[i - carpetLen] == 1){
subAns--;
incr = false;
}
// 当本次循环只发生累加,记录结果
if(incr){
ans = max(ans, subAns);
}
}
return ans;
}
};
超时版本2:
基本思路为:先排序,每次从一个坐标范围的 最小值开始,往下寻找,当满足覆盖范围时结束,记录当前的最大覆盖白色数量。
class Solution {
public:
int maximumWhiteTiles(vector<vector<int>>& tiles, int carpetLen) {
// 排序
sort(begin(tiles), end(tiles), [](auto &ele1, auto &ele2){return ele1[0] <= ele2[0];});
// 返回的最终结果,每次记录的结果
int ans = 0, subAns = 0;
for(int i = 0; i < tiles.size(); i++){
// 当前位置的左坐标
int left = tiles[i][0];
// 结束位置的下一个坐标
int endIndex = left + carpetLen;
// 寻找长度为carpetLen,范围内的左边,并记录白色的数量
for(int j = i; j < tiles.size(); j++){
// 当前未知的坐标
auto &vec = tiles[j];
// 如果当前位置的左坐标大于等于endIndex,则结束循环
if(vec[0] >= endIndex){
break;
}
if(vec[1] >= endIndex){
// endIndex位于当前坐标范围内
// 先记录白色的数量
subAns += (endIndex - vec[0]);
// 在跳出循环
break;
}else{
// 当前坐标范围的right值小于endIndex,则记录这个范围内的所有白色数量
subAns += ((vec[1] - vec[0]) + 1);
}
}
// 如果白色的数量已经等于carpetLen则直接返回
if(carpetLen == (ans = max(ans, subAns))){
return ans;
}
// 置为0
subAns = 0;
}
return ans;
}
};
优化版本 TODO: