2271. 毯子覆盖的最多白色砖块数 ●●

2271. 毯子覆盖的最多白色砖块数 ●●

描述

给你一个二维整数数组 tiles ,其中 t i l e s [ i ] = [ l i , r i ] tiles[i] = [l_i, r_i] tiles[i]=[li,ri] ,表示所有在 l i < = j < = r i l_i <= j <= r_i li<=j<=ri 之间的每个瓷砖位置 j 都被涂成了白色。

同时给你一个整数 carpetLen ,表示可以放在 任何位置 的一块毯子。

请你返回使用这块毯子,最多 可以盖住多少块瓷砖

示例

在这里插入图片描述
输入:tiles = [[1,5],[10,11],[12,18],[20,25],[30,32]], carpetLen = 10
输出:9
解释:将毯子从瓷砖 10 开始放置。
总共覆盖 9 块瓷砖,所以返回 9 。
注意可能有其他方案也可以覆盖 9 块瓷砖。
可以看出,瓷砖无法覆盖超过 9 块瓷砖。

题解

1. 双指针 + 滑动窗口

核心思路:滑动窗口,右指针不断扩大,直到不能继续后移(该段不是完全被覆盖的情况),收缩左指针,让右指针再次尝试扩大。

毯子覆盖情况:

  1. 完全覆盖当前 right 段,则记录长度,右指针右移,计算更多覆盖的长度;
  2. 覆盖部分 right 段,记录长度,毯子(左指针)右移;
  3. 完全不覆盖当前 right 段,毯子(左指针)右移。

  • 时间复杂度: O ( n log ⁡ n ) O(n\log n) O(nlogn),其中 n 为 tiles 的长度。对 tiles 数组排序的时间复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn),双指针维护最多可覆盖数量的时间复杂度为 O(n)。
  • 空间复杂度: O ( log ⁡ n ) O(\log n) O(logn),即为排序的栈空间开销。
class Solution {
public:
    int maximumWhiteTiles(vector<vector<int>>& tiles, int carpetLen) {
        sort(tiles.begin(), tiles.end(), [](vector<int>& a, vector<int>& b){
            return a[0] < b[0];                     // 开头升序排序
        });
        int n = tiles.size();
        int left = 0, right = 0, len = 0, ans = 0;
        while(left <= right && right < n){
            int rightMax = tiles[left][0] + carpetLen - 1;
            if(tiles[right][1] <= rightMax){        // 整段覆盖
                len += tiles[right][1] - tiles[right][0] + 1;
                ans = max(ans, len);
                ++right;                            // 该段全部覆盖的情况下,才继续移动右指针,否则移动左指针
            }else{                                  // 非整段覆盖:该段部分覆盖 / 该段完全不覆盖                   
                if(tiles[right][0] <= rightMax){    // 部分覆盖
                    ans = max(ans, len + rightMax - tiles[right][0] + 1);   // 因为接下来要移动左指针,因此直接比较当前部分覆盖情况下的最长长度
                    if(ans >= carpetLen) return carpetLen;
                }
                // 移动毯子起始位置到下一区间开头
                len -= tiles[left][1] - tiles[left][0] + 1;   
                ++left;       
            }
        } 
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值