Leetcode 850. 長方形領域 II [難しい]

ここに画像の説明を挿入

ps: 昨日は同僚が辞めるのが遅すぎたので、今日は私がその埋め合わせをします。

トピックのリンクと説明

https://leetcode.cn/problems/rectangle-area-ii/
(軸に揃えられた) 2 次元長方形リストの長方形が与えられます。Rectangle[i] = [x1, y1, x2, y2] の場合、(x1, y1) は長方形 i の左下隅の座標、(xi1, yi1) は長方形の左下隅の座標です。 , (xi2, yi2) は、長方形の右上隅の座標です。

平面内のすべての長方形によってカバーされる合計面積を計算します。2 つ以上の長方形で覆われた領域は 1 回だけカウントされます。

総面積を返します。答えが大きすぎる可能性があるため、モジュロ 109 + 7 を返します。

例 1:

入力: 長方形 = [[0,0,2,2],[1,0,2,3],[1,0,3,1]]
出力: 6
説明: 図に示すように、3 つの長方形が A を覆っています。総面積6の地域。
(1,1) から (2,2) まで、緑と赤の長方形が重なっています。
(1,0) から (2,3) まで、3 つの長方形はすべて重なっています。
例 2:

入力:rectangles = [[0,0,1000000000,1000000000]]
出力:49
説明:答えは 1018 モジュロ (109 + 7) の結果、つまり 49 です。

ヒント:

1 <= Rectangles.length <= 200
Rectangles[i].length = 4
0 <= xi1, yi1, xi2, yi2 <= 109
重ね合わされた長方形の総面積は 2^63 - 1 を超えません。つまり、 64 ビットの符号付き整数を使用して領域の結果を保存します。

キーワード: 走査線

偶然かどうかは関係なく、領域を 1 つの等分割した長方形に分割し、y 軸の長さを求め、それを合計して結果を得る、と考えるのは簡単です。

方法 1:

スクリーンショットを実行する

ここに画像の説明を挿入

コード


{
    
    
		// 不考虑重合 很容易想到把区域切分为1等分的矩形,求到y轴长度,然后累加即可得到结果
		// 首先数值需要取模
		long mod = (int) 1e9 + 7;
		// 获得
		List<Integer> xList = new ArrayList<>();
		// 拿到x轴的点集合
		for (int[] info : rectangles) {
    
    
			xList.add(info[0]);
			xList.add(info[2]);
		}
		// 排序
		Collections.sort(xList);
		long ans = 0;
		// 从1开始拿到
		for (int i = 1; i < xList.size(); i++) {
    
    
			int beforeX = xList.get(i - 1), currentX = xList.get(i), len = currentX - beforeX;
			// 因为有重叠,所以可能存在
			if (len == 0) {
    
    
				continue;
			}
			// 然后拿到在这段区域内的 y轴 线段数组
			List<int[]> inYLine = new ArrayList<>();
			for (int[] info : rectangles) {
    
    
				// 如果是包含了当前这段则添加进来
				if (info[0] <= beforeX && currentX <= info[2]) {
    
    
					inYLine.add(new int[]{
    
    info[1], info[3]});
				}
			}
			// 排序,左下角没有重合则先比左下角y,如果重合则比较右上角
			Collections.sort(inYLine, (l1, l2) -> l1[0] != l2[0] ? l1[0] - l2[0] : l1[1] - l2[1]);
			// 加上总面积
			long total = 0, left = -1, right = -1;
			// 循环所有在x轴区域内的y轴线
			for (int[] yRange : inYLine) {
    
    
				// 左小角大于上一个右上角表示没有重叠
				if (yRange[0] > right) {
    
    
					// 记录x段内的总长度为右上角y减去左下角y
					total += right - left;
					// 赋值记录
					left = yRange[0];
					right = yRange[1];
				} else if (yRange[1] > right) {
    
    
					// 如果左下角小于等于上一个右上角 && 右上角大于上一个右上角则不用重复计算
					right = yRange[1];
				}
			}
			// 因为累加是延后一步,所以要再计算一下
			total += right - left;
			// 然后 x 乘 y 得到矩形
			ans += total * len;
			// 取模一下
			ans %= mod;
		}
		return (int) ans;
	}

終わり

コメント エリアでのコミュニケーション、毎日チェックイン、お急ぎください。

おすすめ

転載: blog.csdn.net/qq_35530042/article/details/126888738