zoukankan      html  css  js  c++  java
  • 求最大子矩阵的大小

    【说明】:

      本文是左程云老师所著的《程序员面试代码指南》第一章中“求最大子矩阵的大小”这一题目的C++复现。

      本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。

      感谢左程云老师的支持。

    【题目】:

      给定一个整型矩阵 map,其中的值只有 0 和 1 两种,求其中全是1的所有矩形区域中,最大的矩形区域为1的数量。

      例如:

      1  1  1  0

      其中,最大的矩形区域有 3 个 1,所以返回3。

      再如:

      1  0  1  1

      1  1  1  1

      1  1  1  0

      其中,最大的矩形区域有 6 个 1,所以返回6。

     【思路】:

      简单已经不足以描述了,请参考左老师的原书。

    【编译环境】:

      CentOS6.7(x86_64)

      gcc 4.4.7

     【实现】:

      实现及测试代码:

     1 /*
     2  *文件名:maxRecSize.cpp
     3  *作者:
     4  *摘要:使用C++实现最大子矩阵的问题
     5  */
     6  
     7 #include <iostream>
     8 #include <stack>
     9 #include <algorithm>
    10 
    11 using namespace std;
    12 
    13 int maxRecFromBottom(int count[],int len)
    14 {
    15     if(NULL == count || len <=0 )
    16         return 0;
    17     int maxArea = 0;
    18     stack<int> s;
    19     for(int i=0; i<len; i++)
    20     {
    21         while(!s.empty() && count[i] <= count[s.top()])
    22         {
    23             //当前的数据位置为i
    24             int j = s.top();    //弹出的栈顶数据标记为j
    25             s.pop();
    26             int k = s.empty() ? -1 : s.top();    //新的栈顶标记为k
    27             int curArea = (i-k-1) * count[j];
    28             maxArea = max(curArea,maxArea);
    29         }
    30         s.push(i);
    31     }
    32     while(!s.empty())
    33     {
    34         int j = s.top();
    35         s.pop();
    36         int k = s.empty() ? -1 : s.top();
    37         int i = len;    //在len处虽然没有数据,但是len可做为右边界
    38         int curArea = (i-k-1)*count[j];
    39         maxArea = max(curArea,maxArea);
    40     }
    41     return maxArea;
    42 }
    43 
    44 int maxRecSize(int **mat,const int length,const int height)
    45 {
    46     if(NULL == mat || 0 >= length || 0 >= height )
    47         return 0;
    48     int maxArea = 0;
    49     int *count = new int[length]();
    50     for(int i=0; i<height; i++)
    51     {
    52         for(int j=0; j<length; j++)
    53         {
    54             count[j] = ((mat+i)[j] == 0 ? 0 : count[j]+1);
    55         }
    56         cout << "--------" << endl;
    57         maxArea = max(maxRecFromBottom(count,length),maxArea);
    58     }
    59     return maxArea;
    60 }
    61 
    62 int main()
    63 {
    64     int mat[][4] = {{1,0,1,1},{1,1,1,1},{1,1,1,0}};
    65     cout << "maxRecSize is : " << maxRecSize((int **)mat,4,3) << endl;
    66     return 0;
    67 }
    View Code

    【说明】

      1、一维数组初始化时碰到一个问题:

        我声明的原代码为:

        int count[length] = {0};               // 错误:可变大小的对象‘count’不能被初始化

        后改为:

        int *count = new int[length]();        //这种情况就可以实现内将为count分配的内存初始化为0

        关于C++中使用 new 时,数组初始化的问题请参考:[C++]数组初始化

        重点:(错误:ISO C++ 不允许在数组 new 中初始化)new数组只能用无参的构造函数或者所有参数都有默认值的构造函数,new[](new的数组版)要求元素对象的类型必须具有默认构造函数(内建类型的“默认构造函数”是什么也不做),否则将不能使用new[]。

      2、二维指针做形参的问题请参考:[总结]C语言二维数组作为函数的参数

      3、使用二维指针访问二维数组时需要注意的请参考:二维数组和二级指针

    注:

      转载请注明出处;

      转载请注明源思路来自于左程云老师的《程序员代码面试指南》

  • 相关阅读:
    解决VTune错误.../lib64/libstdc++.so.6: version `GLIBCXX_3.4.14&#39; not found (required by ...)
    【环境配置】配置sdk
    Eclipse设置Android Logcat输出字体大小
    Vertica数据库操作
    hihoCoder#1038 : 01背包
    初识Dubbo 系列之4-Dubbo 依赖
    计算机相关专业的同学该怎么用自己的计算机
    十天学习PHP之第三天
    Android之Fragment的优点和作用
    Fragment的生命周期
  • 原文地址:https://www.cnblogs.com/PrimeLife/p/5346882.html
Copyright © 2011-2022 走看看