zoukankan      html  css  js  c++  java
  • 最大矩形, 统计全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;
        }
    }
    
  • 相关阅读:
    Balance的数学思想构造辅助函数
    1663. Smallest String With A Given Numeric Value (M)
    1680. Concatenation of Consecutive Binary Numbers (M)
    1631. Path With Minimum Effort (M)
    1437. Check If All 1's Are at Least Length K Places Away (E)
    1329. Sort the Matrix Diagonally (M)
    1657. Determine if Two Strings Are Close (M)
    1673. Find the Most Competitive Subsequence (M)
    1641. Count Sorted Vowel Strings (M)
    1679. Max Number of K-Sum Pairs (M)
  • 原文地址:https://www.cnblogs.com/lixyuan/p/13288574.html
Copyright © 2011-2022 走看看