JavaInterview JavaInterview
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)

『Java面试+Java学习』
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)
  • 指南
  • 简历

  • Java

  • 面试

  • 算法

  • algorithm
  • leetcode
JavaInterview.cn
2024-09-28
目录

元素和小于等于阈值的正方形的最大边长Java

文章发布较早,内容可能过时,阅读注意甄别。

# 题目

给你一个大小为 m x n 的矩阵 mat 和一个整数阈值 threshold。

请你返回元素总和小于或等于阈值的正方形区域的最大边长;如果没有这样的正方形区域,则返回 0 。

示例 1: e1(1).png

输入:mat = [[1,1,3,2,4,3,2],[1,1,3,2,4,3,2],[1,1,3,2,4,3,2]], threshold = 4
输出:2
解释:总和小于或等于 4 的正方形的最大边长为 2,如图所示。

示例 2:

输入: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
输出:0

提示:

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n <= 300
  • 0 <= mat[i][j] <= 104
  • 0 <= threshold <= 105

# 思路

前缀和

# 解法

class Solution {
    public int maxSideLength(int[][] mat, int threshold) {
        /*
         * 涉及知识点 : 1、 前缀和  2、 容斥原理
         *              容斥原理:
         *                  正方形面积 = 已求出的矩形面积运算得出

         *                  sum[i][j] = mat[i][j] + sum[i - 1][j] + 
         *                              sum[i][j - 1] - sum[i - 1][j - 1]

         *                  1  1  1      1  1     1  1  1       1  1
         *                  1  1  1    = 1  1  +  1  1  1   -   1  1  +       
         *                  1  1  1      1  1                             1

         *                  ->  9 = 6 + 6 - 4 + 1
         *              前缀和:
         *                  计算所有位置面积以方便求解过程中使用         
         */
        int m = mat.length;
        int n = mat[0].length;
        int res = 0;
        int[][] sum = new int[m + 1][n + 1];         

        // 根据容斥原理计算前缀和
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                sum[i][j] = mat[i - 1][j - 1] + sum[i][j - 1]
                            + sum[i - 1][j] - sum[i - 1][j - 1];
            }
        }

        // 根据所求出前缀和求解
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                for (int k = 1; k <= i && k <= j; k++) {  
                    // 从边长为1开始扩展正方形大小
                    int ans = sum[i][j] - sum[i - k][j] - sum[i][j - k] + sum[i - k][j - k];
                    if (ans > threshold) {
                        break;
                    }
                    res = Math.max(res, k);
                }
            }
        }
        return res;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

# 总结

  • 分析出几种情况,然后分别对各个情况实现
微信 支付宝
#Java
最近更新
01
1686. 石子游戏VI Java
08-18
02
1688. 比赛中的配对次数 Java
08-18
03
1687. 从仓库到码头运输箱子 Java
08-18
更多文章>
Theme by Vdoing | Copyright © 2019-2025 JavaInterview.cn
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式