LeetCode 1292 Maximum Side Length of a Square

in 网站建设
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

Given a m x n matrix mat and an integer threshold. Return the maximum side-length of a square with a sum less than or equal to threshold or return 0 if there is no such square.

Example 1:

Input: mat = [[1,1,3,2,4,3,2],[1,1,3,2,4,3,2],[1,1,3,2,4,3,2]], threshold = 4
Output: 2
Explanation: The maximum side length of square with sum less than 4 is 2 as shown.

Example 2:

Input: mat = [[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2]], threshold = 1
Output: 0

Example 3:

Input: mat = [[1,1,1,1],[1,0,0,0],[1,0,0,0],[1,0,0,0]], threshold = 6
Output: 3

Example 4:

Input: mat = [[18,70],[61,1],[25,85],[14,40],[11,96],[97,96],[63,45]], threshold = 40184
Output: 2

Constraints:

输入一个二维数组mat和一个整数treshold.
二维数组代表一个矩形,对于其中的正方形,(正方形所包含的点的和值小于等于treshold),返回最大的那个正方形的边长。
方法1:暴力搜索。

// O(m*n*min(m,n))
public int maxSideLength(int[][] mat, int threshold) {
    int m = mat.length, n = mat[0].length;
    int[][] dp = new int[m + 1][n + 1];
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            dp[i][j] = dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1] + mat[i - 1][j - 1];
        }
    }
    int ans = 0;
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            for (int k = 0; i + k <= m && j + k <= n; k++) {
                // 计算矩形面积
                int area = rangeSum(i, j, i + k, j + k, dp);
                if (area > threshold) break;
                ans = Math.max(ans, k + 1);
            }
        }
    }
    return ans;
}

// 求以[x1, y1]点为左上角,[x2, y2]点为右下角的矩形的面积
private int rangeSum(int x1, int y1, int x2, int y2, int[][] dp) {
    return dp[x2][y2] - dp[x2][y1 - 1] - dp[x1 - 1][y2] + dp[x1 - 1][y1 - 1];
}

把k初始化时,直接替换成ans,可以把时间复杂度降低为平方级。
image.png
再看binary search方法:

class Solution {
    // O(m*n*lg(min(m,n))
    public int maxSideLength(int[][] mat, int threshold) {
        int m = mat.length, n = mat[0].length;
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1] + mat[i - 1][j - 1];
            }
        }
        int ans = 0;
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                // 可以用binary search 把时间复杂度从m*n*min(m,n)降为m*n*lg(min(m,n))
                int left = 0, right = Math.min(m - i, n - j) + 1;
                while (left < right) {
                    int mid = left + (right - left) / 2;
                    if (rangeSum(i, j, i + mid, j + mid, dp) > threshold) {
                        right = mid;
                    } else {
                        left = mid + 1;
                    }
                }
                ans = Math.max(ans, left);
            }
        }
        return ans;
    }

    // 求以[x1, y1]点为左上角,[x2, y2]点为右下角的矩形的面积
    private int rangeSum(int x1, int y1, int x2, int y2, int[][] dp) {
        return dp[x2][y2] - dp[x2][y1 - 1] - dp[x1 - 1][y2] + dp[x1 - 1][y1 - 1];
    }
}
https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1292-maximum-side-length-of-a-square-with-sum-less-than-or-equal-to-threshold/
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看