列表

详情


LCP 74. 最强祝福力场

小扣在探索丛林的过程中,无意间发现了传说中“落寞的黄金之都”。而在这片建筑废墟的地带中,小扣使用探测仪监测到了存在某种带有「祝福」效果的力场。 经过不断的勘测记录,小扣将所有力场的分布都记录了下来。forceField[i] = [x,y,side] 表示第 i 片力场将覆盖以坐标 (x,y) 为中心,边长为 side 的正方形区域。

若任意一点的 力场强度 等于覆盖该点的力场数量,请求出在这片地带中 力场强度 最强处的 力场强度

注意:

示例 1:

输入: forceField = [[0,0,1],[1,0,1]]

输出:2

解释:如图所示,(0.5, 0) 处力场强度最强为 2, (0.5,-0.5)处力场强度同样是 2。 image.png{:width=400px}

示例 2:

输入: forceField = [[4,4,6],[7,5,3],[1,6,2],[5,6,3]]

输出:3

解释:如下图所示, forceField[0]、forceField[1]、forceField[3] 重叠的区域力场强度最大,返回 3 image.png{:width=500px}

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int fieldOfGreatestBlessing(vector<vector<int>>& forceField) { } };

java 解法, 执行用时: 14 ms, 内存消耗: 41.8 MB, 提交时间: 2023-04-23 10:44:46

class Solution {
	int[][] diff;
	int m, n;
	
    public int fieldOfGreatestBlessing(int[][] forceField) {
		// 1. 统计所有左下和右上坐标
		var xSet = new HashSet<Long>();
		var ySet = new HashSet<Long>();
		int i = 0, j = 0, side = 0;
		for(int[] f : forceField) {
		    i = f[0];
		    j = f[1];
			side = f[2];

			xSet.add(1l * 2 * i - side); //由于会出现0.5, 所以将坐标乘 2
			xSet.add(1l * 2 * i + side);

			ySet.add(1l * 2 * j - side);
			ySet.add(1l * 2 * j + side);
		}

		// 2. 离散化
		int m = xSet.size(), n = ySet.size();
		var xs = new ArrayList<Long>();
		for(long e : xSet) xs.add(e);
		Collections.sort(xs, (a, b)->a.compareTo(b));
			
		var ys = new ArrayList<Long>();
		for(long e : ySet) ys.add(e);
		Collections.sort(ys, (a, b)->a.compareTo(b));

		// 3. 二维差分
		diff = new int[m + 2][n + 2];
		long x = 0, y = 0;
		int r1 = 0, r2 = 0, c1 = 0, c2 = 0;

		for(int[] p : forceField){
			i = p[0];
			j = p[1];
			side = p[2];
			x = 2 * 1l * i - side;
			y = 2 * 1l * j - side;
			r1 = binarySearch(xs, x);
            c1 = binarySearch(ys, y);


			x = 2 * 1l * i + side;
			y = 2 * 1l * j + side;
			r2 = binarySearch(xs, x);
			c2 = binarySearch(ys, y);

			update(r1, c1, r2, c2);
		}

		// 4. 计算最大值
		int res = 0;
		for(i = 1; i <= m; ++i) {
			for(j = 1; j <= n; ++j){
				//前缀和公式
				diff[i][j] += diff[i - 1][j] + diff[i][j - 1] - diff[i - 1][j - 1];
				res = Math.max(res, diff[i][j]);
			}
		}
		return res;
    }
        
	public void update(int r1, int c1, int r2, int c2) {
		++diff[r1 + 1][c1 + 1];
        ++diff[r2 + 2][c2 + 2];
		--diff[r2 + 2][c1 + 1];
		--diff[r1 + 1][c2 + 2];
	}
	
	public int binarySearch(List<Long> arr, long t) {
		 int mid = 0;
		 int l = -1, r = arr.size();
		 while(l + 1 < r){
			mid = (l + r) >>> 1;
			if(Long.compare(arr.get(mid), t) < 0) l = mid;
			else r = mid;
		 }
		 return r;
	}
}

cpp 解法, 执行用时: 20 ms, 内存消耗: 10.2 MB, 提交时间: 2023-04-23 10:39:05

#define ll long long
class Solution {
public:
    int fieldOfGreatestBlessing(vector<vector<int>>& forceField) {
       	int ans = 0;
        set<ll>x_set;
        set<ll>y_set;
		for(auto&p : forceField){
            ll i = p[0], j = p[1], len = p[2];
            ll x2 = 2 * i + len, x1 = 2 * i - len;
            ll y2 = 2 * j + len, y1 = 2 * j - len;
            x_set.insert(x1), x_set.insert(x2);
            y_set.insert(y1), y_set.insert(y2);
        } 
        vector<ll>ax{x_set.begin(), x_set.end()};
        vector<ll>ay{y_set.begin(), y_set.end()};
        auto find = [&](auto & nums, ll val){
            return lower_bound(nums.begin(), nums.end(), val) - nums.begin();
        };
        int n = ax.size(), m = ay.size();
        int diff[n + 2][m + 2];
        memset(diff, 0, sizeof(diff));
        for(auto& p : forceField){
            ll i = p[0], j = p[1], len = p[2];
            ll x2 = 2 * i + len, x1 = 2 * i - len;
            ll y2 = 2 * j + len, y1 = 2 * j - len;
            x2 = find(ax, x2), x1 = find(ax, x1);
            y2 = find(ay, y2), y1 = find(ay, y1);
            diff[x1 + 1][y1 + 1]++;
            diff[x2 + 2][y1 + 1]--;
            diff[x1 + 1][y2 + 2]--;
            diff[x2 + 2][y2 + 2]++;
        }
        for(int i = 1; i <= n;++i){
            for(int j = 1; j <= m;++j){
                diff[i][j] += diff[i - 1][j] + diff[i][j - 1] - diff[i - 1][j - 1];
                ans = max(ans, diff[i][j]);
            }	
        }
        return ans;
    }
};

python3 解法, 执行用时: 232 ms, 内存消耗: 15.5 MB, 提交时间: 2023-04-23 10:38:25

class Solution:
    def fieldOfGreatestBlessing(self, forceField: List[List[int]]) -> int:
        # 1.统计所有左下和右上坐标
        xSet = set()
        ySet = set()
        for f in forceField:
            i, j, side = f[0], f[1], f[2]
            x = 2 * i - side
            y = 2 * j - side
            xSet.add(x)
            ySet.add(y)
            x = 2 * i + side
            y = 2 * j + side
            xSet.add(x)
            ySet.add(y)
    
        # 2.离散化
        xs = sorted(list(xSet))
        ys = sorted(list(ySet))
    
        # 3.二维差分
        n, m = len(xs), len(ys)
        diff = [[0] * (m + 2) for _ in range(n + 2)]
    
        def update(r1, c1, r2, c2):
            diff[r1 + 1][c1 + 1] += 1
            diff[r1 + 1][c2 + 2] -= 1
            diff[r2 + 2][c1 + 1] -= 1
            diff[r2 + 2][c2 + 2] += 1
    
        for p in forceField:
            i, j, side = p[0], p[1], p[2]
            x = 2 * i - side
            y = 2 * j - side
            r1 = xs.index(x)
            c1 = ys.index(y)
            x = 2 * i + side
            y = 2 * j + side
            r2 = xs.index(x)
            c2 = ys.index(y)
            update(r1, c1, r2, c2)
            
        # 4.复原,计算最大值
        ans = 0
        for i in range(1, n + 1):
            for j in range(1, m + 1):
                diff[i][j] += diff[i][j - 1] + diff[i - 1][j] - diff[i - 1][j - 1]
                ans = max(ans, diff[i][j]) if ans < diff[i][j] else ans
    
        return ans

golang 解法, 执行用时: 8 ms, 内存消耗: 6.6 MB, 提交时间: 2023-04-23 10:37:24

func fieldOfGreatestBlessing(forceField [][]int) (ans int) {
	// 1. 统计所有左下和右上坐标
	xSet := map[int]bool{}
	ySet := map[int]bool{}
	for _, f := range forceField {
		i, j, side := f[0], f[1], f[2]
		x := 2*i - side
		y := 2*j - side
		xSet[x] = true
		ySet[y] = true
		x = 2*i + side
		y = 2*j + side
		xSet[x] = true
		ySet[y] = true
	}

	// 2. 离散化
	n, m := len(xSet), len(ySet)
	xs := make([]int, 0, n)
	for x := range xSet {
		xs = append(xs, x)
	}
	sort.Ints(xs)
	ys := make([]int, 0, m)
	for y := range ySet {
		ys = append(ys, y)
	}
	sort.Ints(ys)

	// 3. 二维差分
	diff := make([][]int, n+2)
	for i := range diff {
		diff[i] = make([]int, m+2)
	}
	update := func(r1, c1, r2, c2 int) {
		diff[r1+1][c1+1]++
		diff[r1+1][c2+2]--
		diff[r2+2][c1+1]--
		diff[r2+2][c2+2]++
	}
	for _, p := range forceField {
		i, j, side := p[0], p[1], p[2]
		x := 2*i - side
		y := 2*j - side
		r1 := sort.SearchInts(xs, x)
		c1 := sort.SearchInts(ys, y)
		x = 2*i + side
		y = 2*j + side
		r2 := sort.SearchInts(xs, x)
		c2 := sort.SearchInts(ys, y)
		update(r1, c1, r2, c2)
	}

	// 4. 复原,计算最大值
	for i := 1; i <= n; i++ {
		for j := 1; j <= m; j++ {
			diff[i][j] += diff[i][j-1] + diff[i-1][j] - diff[i-1][j-1]
			ans = max(ans, diff[i][j])
		}
	}
	return
}

func max(a, b int) int { if a < b { return b }; return a }

上一题