返回介绍

solution / 2200-2299 / 2271.Maximum White Tiles Covered by a Carpet / README

发布于 2024-06-17 01:03:08 字数 4859 浏览 0 评论 0 收藏 0

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

English Version

题目描述

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

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

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

 

示例 1:

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

示例 2:

输入:tiles = [[10,11],[1,1]], carpetLen = 2
输出:2
解释:将毯子从瓷砖 10 开始放置。
总共覆盖 2 块瓷砖,所以我们返回 2 。

 

提示:

  • 1 <= tiles.length <= 5 * 104
  • tiles[i].length == 2
  • 1 <= li <= ri <= 109
  • 1 <= carpetLen <= 109
  • tiles 互相 不会重叠 。

解法

方法一:贪心 + 排序 + 滑动窗口

直觉上,毯子的左端点一定与某块瓷砖的左端点重合,这样才能使得毯子覆盖的瓷砖最多。

我们可以来简单证明一下。

如果毯子落在某块瓷砖的中间某个位置,将毯子右移一个,毯子覆盖的瓷砖数量可能减少,也可能不变,但不可能增加;将毯子左移一个,毯子覆盖的瓷砖数量可能不变,也可能增加,但不可能减少。

也就是说,将毯子左移至某块瓷砖的左端点,一定可以使得毯子覆盖的瓷砖数量最多。

因此,我们可以将所有瓷砖按照左端点从小到大排序,然后枚举每块瓷砖的左端点,计算出以该左端点为起点的毯子覆盖的瓷砖数量,取最大值即可。

为了计算以某块瓷砖的左端点为起点的毯子覆盖的瓷砖数量,我们可以使用滑动窗口的思想,维护一个右端点不断右移的窗口,窗口内的瓷砖数量即为毯子覆盖的瓷砖数量。

时间复杂度 $O(n\log n)$,其中 $n$ 为瓷砖的数量。

class Solution:
  def maximumWhiteTiles(self, tiles: List[List[int]], carpetLen: int) -> int:
    tiles.sort()
    n = len(tiles)
    s = ans = j = 0
    for i, (li, ri) in enumerate(tiles):
      while j < n and tiles[j][1] - li + 1 <= carpetLen:
        s += tiles[j][1] - tiles[j][0] + 1
        j += 1
      if j < n and li + carpetLen > tiles[j][0]:
        ans = max(ans, s + li + carpetLen - tiles[j][0])
      else:
        ans = max(ans, s)
      s -= ri - li + 1
    return ans
class Solution {
  public int maximumWhiteTiles(int[][] tiles, int carpetLen) {
    Arrays.sort(tiles, (a, b) -> a[0] - b[0]);
    int n = tiles.length;
    int s = 0, ans = 0;
    for (int i = 0, j = 0; i < n; ++i) {
      while (j < n && tiles[j][1] - tiles[i][0] + 1 <= carpetLen) {
        s += tiles[j][1] - tiles[j][0] + 1;
        ++j;
      }
      if (j < n && tiles[i][0] + carpetLen > tiles[j][0]) {
        ans = Math.max(ans, s + tiles[i][0] + carpetLen - tiles[j][0]);
      } else {
        ans = Math.max(ans, s);
      }
      s -= (tiles[i][1] - tiles[i][0] + 1);
    }
    return ans;
  }
}
class Solution {
public:
  int maximumWhiteTiles(vector<vector<int>>& tiles, int carpetLen) {
    sort(tiles.begin(), tiles.end());
    int s = 0, ans = 0, n = tiles.size();
    for (int i = 0, j = 0; i < n; ++i) {
      while (j < n && tiles[j][1] - tiles[i][0] + 1 <= carpetLen) {
        s += tiles[j][1] - tiles[j][0] + 1;
        ++j;
      }
      if (j < n && tiles[i][0] + carpetLen > tiles[j][0]) {
        ans = max(ans, s + tiles[i][0] + carpetLen - tiles[j][0]);
      } else {
        ans = max(ans, s);
      }
      s -= (tiles[i][1] - tiles[i][0] + 1);
    }
    return ans;
  }
};
func maximumWhiteTiles(tiles [][]int, carpetLen int) int {
  sort.Slice(tiles, func(i, j int) bool { return tiles[i][0] < tiles[j][0] })
  n := len(tiles)
  s, ans := 0, 0
  for i, j := 0, 0; i < n; i++ {
    for j < n && tiles[j][1]-tiles[i][0]+1 <= carpetLen {
      s += tiles[j][1] - tiles[j][0] + 1
      j++
    }
    if j < n && tiles[i][0]+carpetLen > tiles[j][0] {
      ans = max(ans, s+tiles[i][0]+carpetLen-tiles[j][0])
    } else {
      ans = max(ans, s)
    }
    s -= (tiles[i][1] - tiles[i][0] + 1)
  }
  return ans
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文