• 最大矩形, 统计全1子矩阵


    美团笔试题-最大矩形

    暴力直接解决, 输入处理较为麻烦。
    LeetCode 85 一样。

    import java.util.*;
    public class Main {
        static int solve(int[][] arr, int n, int m) {
            int area = 0;
            for(int a = 0; a < n; a++){
                for(int b = 0; b < m; b++) {
                    for(int c = 0; c <= a; c++){
                        for(int d = 0; d <= b; d++) {
                            int t = 0;
                            for(int i=c; i <= a; i++)
                                for(int j=d; j <= b; j++)
                                    if(arr[i][j] == 1) t++;
                            if(t == (a-c+1)*(b-d+1))
                                area = Math.max(area, t);
                        }
                    }
                }
            }
            return area;
        }
        public static void main(String[] args){
            Scanner sc = new Scanner(System.in);
            if(sc.hasNext()) sc.nextLine();
            List<String> list = new ArrayList<>();
            while(true){
                char[] s = sc.nextLine().toCharArray();
                StringBuilder sb = new StringBuilder();
                for(int i=0; i < s.length;i++)
                    if(s[i] == '0' || s[i] == '1')
                        sb.append(s[i]);
                if(sb.length() == 0) break;
                list.add(sb.toString());
                if(s[s.length-1] != ',') break;
            }
            if(sc.hasNext()) sc.nextLine();
            int n = list.size(), m = list.get(0).length();
            int[][] a = new int[n][m];
            for(int i=0; i < n; i++)
                for(int j=0; j < m; j++)
                    a[i][j] = list.get(i).charAt(j) == '1' ? 1 : 0;
            int area = solve(a, n, m);
     
            System.out.println(area);
        }
    }
    
    

    Leetcode 1504. 统计全1子矩阵

    N, M <= 150
    使用二维前缀和优化,时间复杂度:O(N*M*N*M)

    class Solution {
        public int numSubmat(int[][] mat) {
            int n = mat.length, m = mat[0].length;
            int[][] f = new int[n+1][m+1];
            for(int i=1; i <= n; i++)
                for(int j=1; j <= m; j++) {
                    f[i][j] = f[i-1][j]+f[i][j-1]-f[i-1][j-1];
                    if(mat[i-1][j-1] == 1) f[i][j]++;
                }
            int count = 0;
            for(int a = 1; a <= n; a++) {
                for(int b=1; b <= m; b++) {
                    for(int c=1; c <= a; c++) {
                        for(int d=1; d <= b; d++) {
                            int t = f[a][b] - f[a][d-1] - f[c-1][b] + f[c-1][d-1];
                            if(t == (a-c+1)*(b-d+1))
                                count++;
                        }
                    }
                }
            }
            return count;
        }
    }
    

    优化版思路:

    1. 求出每行的前缀和
    2. 遍历所有可能子矩阵的左列和右列, 根据前缀和和以计算出每一行左列到右列间1的数量。
    3. 遍历行, 连续x行每行左列到右列间全为1,则有 x(x+1)/2 种矩阵。
      时间复杂度:O(N*M*M)
    class Solution {
        public int numSubmat(int[][] mat) {
            int n = mat.length, m = mat[0].length;
            int[][] f = new int[n][m+1]; //每行的前缀和
            for(int i=0; i < n; i++) {
                for(int j=1; j <= m; j++)
                    f[i][j] = f[i][j-1] + mat[i][j-1];
            }
            int count = 0;
            for(int a = 0; a < m; a++) { // 矩阵左列
                for(int b=a; b < m; b++) { // 矩阵右列
                    int cnt = 0;
                    for(int i=0; i < n; i++) {
                        int sum = f[i][b+1] - f[i][a];
                        if(sum == b-a+1)
                            cnt++;
                        else {
                            count += cnt*(cnt+1) / 2;
                            cnt = 0;
                        }
                    }
                    if(cnt != 0) count += cnt*(cnt+1) / 2;
                }
            }
            return count;
        }
    }
    
  • 相关阅读:
    【BootStrap】 布局组件 I
    【BootStrap】 概述 & CSS
    【Python】 Selenium 模拟浏览器 寻路
    【jQuery】 JQ和AJAX
    【jQuery】 JQ和HTML以及JQ遍历元素
    【Zabbix】 ZBX的豆知识
    【XML】 XML格式一些记录
    【jQuery】 jQuery基础
    php微信开发 -- 两种运营模式及服务器配置
    nodejs基础 -- 函数
  • 原文地址:https://www.cnblogs.com/lixyuan/p/13288574.html
Copyright © 2020-2023  润新知