2014-04-29 04:30

题目:给定一个由‘0’或者‘1’构成的二维数组,找出一个四条边全部由‘1’构成的正方形(矩形中间可以有‘0’),使得矩形面积最大。

解法:用动态规划思想,记录二维数组每个元素向上下左右四个方向各有多少个连续的‘1’,然后用O(n^3)时间计算出满足条件的最大正方形。时间复杂度O(n^3),空间复杂度O(n^2)。

代码:

  1 // 18.11 Given an NxN matrix of 0s and 1s, find out a subsquare whose all four borders are all 1s. If multiple satisfies the condition, any one is OK.
  2 // I'll return the size and the left top corner of the subsquare.
  3 #include <iostream>
  4 #include <vector>
  5 using namespace std;
  6
  7 class Solution {
  8 public:
  9     void maxSubsquare(const vector<vector<int> > &matrix, int &max_left, int &max_top, int &max_size) {
 10         int n = matrix.size();
 11
 12         max_left = max_top = max_size = -1;
 13
 14         if (n <= 1) {
 15             return;
 16         }
 17
 18         vector<vector<int> > top   (n, vector<int>(n));
 19         vector<vector<int> > bottom(n, vector<int>(n));
 20         vector<vector<int> > left  (n, vector<int>(n));
 21         vector<vector<int> > right (n, vector<int>(n));
 22
 23         int i, j;
 24         int tmp;
 25
 26         // use DP to preprocess the data, count how many consecutive 1s are there to the left, right, top, bottom of matrix[i][j].
 27         for (i = 0; i <= n - 1; ++i) {
 28             tmp = 0;
 29             for (j = 0; j <= n - 1; ++j) {
 30                 left[i][j] = matrix[i][j] ? (++tmp) : (tmp = 0);
 31             }
 32         }
 33         for (j = 0; j <= n - 1; ++j) {
 34             tmp = 0;
 35             for (i = 0; i <= n - 1; ++i) {
 36                 top[i][j] = matrix[i][j] ? (++tmp) : (tmp = 0);
 37             }
 38         }
 39         for (i = n - 1; i >= 0; --i) {
 40             tmp = 0;
 41             for (j = n - 1; j >= 0; --j) {
 42                 right[i][j] = matrix[i][j] ? (++tmp) : (tmp = 0);
 43             }
 44         }
 45         for (j = n - 1; j >= 0; --j) {
 46             tmp = 0;
 47             for (i = n - 1; i >= 0; --i) {
 48                 bottom[i][j] = matrix[i][j] ? (++tmp) : (tmp = 0);
 49             }
 50         }
 51
 52         int len;
 53         // O(n ^ 3) solution with O(n ^ 2) space usage.
 54         for (i = 0; i < n; ++i) {
 55             for (j = 0; j < n; ++j) {
 56                 for (len = 2; len + i <= n && len + j <= n; ++len) {
 57                     if (right[i][j] < len || bottom[i][j] < len) {
 58                         continue;
 59                     }
 60                     if (left[i][j + len - 1] < len || bottom[i][j + len - 1] < len) {
 61                         continue;
 62                     }
 63                     if (right[i + len - 1][j] < len || top[i + len - 1][j] < len) {
 64                         continue;
 65                     }
 66                     if (left[i + len - 1][j + len - 1] < len || top[i + len - 1][j + len - 1] < len) {
 67                         continue;
 68                     }
 69                     // all four borders are '1's.
 70                     if (len > max_size) {
 71                         max_top = i;
 72                         max_left = j;
 73                         max_size = len;
 74                     }
 75                 }
 76             }
 77         }
 78
 79         // clear up data
 80         for (i = 0; i < n; ++i) {
 81             left[i].clear();
 82             right[i].clear();
 83             top[i].clear();
 84             bottom[i].clear();
 85         }
 86         left.clear();
 87         right.clear();
 88         top.clear();
 89         bottom.clear();
 90     };
 91 };
 92
 93 int main()
 94 {
 95     int n;
 96     int i, j;
 97     vector<vector<int> > matrix;
 98     Solution sol;
 99     int max_left, max_top, max_size;
100
101     while (cin >> n && n > 0) {
102         matrix.resize(n);
103         for (i = 0; i < n; ++i) {
104             matrix[i].resize(n);
105         }
106
107         for (i = 0; i < n; ++i) {
108             for (j = 0; j < n; ++j) {
109                 cin >> matrix[i][j];
110             }
111         }
112
113         sol.maxSubsquare(matrix, max_left, max_top, max_size);
114         if (max_size > 0) {
115             cout << max_top << ' ' << max_left << endl;
116             cout << max_top << ' ' << max_left + max_size - 1 << endl;
117             cout << max_top + max_size - 1 << ' ' << max_left << endl;
118             cout << max_top + max_size - 1 << ' ' << max_left + max_size - 1 << endl;
119         } else {
120             cout << "No subsquare found." << endl;
121         }
122
123         for (i = 0; i < n; ++i) {
124             matrix[i].clear();
125         }
126         matrix.clear();
127     }
128
129     return 0;
130 }

转载于:https://www.cnblogs.com/zhuli19901106/p/3698379.html

《Cracking the Coding Interview》——第18章:难题——题目11相关推荐

  1. Cracking the coding interview

    转自:http://hawstein.com/posts/ctci-solutions-contents.html Cracking the coding interview--问题与解答 March ...

  2. 经典算法题目:Cracking the coding interview 问题与解答

    Cracking the coding interview--问题与解答 March 14, 2013 作者:Hawstein 出处: http://hawstein.com/posts/ctci-s ...

  3. [Free] Cracking the Coding Interview 6th Download

    [Free] Cracking the Coding Interview 6th Download 推荐给有梯子的童鞋们! https://www.pdfdrive.com/cracking-the- ...

  4. 渣基础:比照Hawstein学Cracking the coding interview(1)

    <C++ Primer 第五版>书实在是太长,太厚了.总是看了十几页就看累了,坚持不了多久,想了想还是别勉强自己,决定把它当工具书查看,或者积累足够的C++经验后再翻阅一遍. 目前的打算是 ...

  5. cracking the coding interview 中文版 (程序员面试金典)

    转自:CTCI面试系列--谷歌面试官经典作品 | 快课网 谷歌面试官经典作品(CTCI)目录 1.1 判断一个字符串中的字符是否唯一 1.2 字符串翻转 1.3 去除字符串中重复字符 1.8 利用已知 ...

  6. 《Cracking the Coding Interview》——第18章:难题——题目3

    2014-04-29 01:02 题目:从m个整数里随机选出n个整数,要求等概率. 解法:和洗牌的算法类似,每次随机抽出一个数,抽n次即可.时间复杂度O(m * n),空间复杂度O(m). 代码: 1 ...

  7. 《Cracking the Coding Interview》——第16章:线程与锁——题目3

    2014-04-27 19:26 题目:哲学家吃饭问题,死锁问题经典模型(专门用来黑哲学家的?). 解法:死锁四条件:1. 资源互斥.2. 请求保持.3. 非抢占.4. 循环等待.所以,某砖家拿起一只 ...

  8. 《Cracking the Coding Interview》——第11章:排序和搜索——题目7

    2014-03-21 22:05 题目:给你N个盒子堆成一座塔,要求下面盒子的长和宽都要严格大于上面的.问最多能堆多少个盒子? 解法1:O(n^2)的动态规划解决.其实是最长递增子序列问题,所以也可以 ...

  9. 《Cracking the Coding Interview》——第9章:递归和动态规划——题目8

    2014-03-20 04:04 题目:给你不限量的1分钱.5分钱.10分钱.25分钱硬币,凑成n分钱总共有多少种方法? 解法:理论上来说应该是有排列组合的公式解的,但推导起来太麻烦而且换个数据就又得 ...

最新文章

  1. 为了进行差错控制,必须对传送的数据帧进行校验。在局域网中广泛使用的校验方法是循环冗余校验。当接收端发现错误后采取的措施是
  2. Uber将整体式API拆分为微服务
  3. ipch文件夹和.sdf文件
  4. 皮一皮:叫车就要叫这样的,霸气...
  5. tomcat的热部署
  6. Scanner类、Random类、ArrayList类
  7. 微信小程序 引用 map 地图,显示当前位置
  8. 博士当中学老师是“人才浪费”?
  9. R语言学习笔记(一)R语言的基本操作与函数
  10. primefaces教程_Primefaces日历组件示例教程
  11. 链路负载需求及基本原理
  12. redis缓存和mysql数据库同步
  13. imx8mm yocto_bsp 编译
  14. react自定义鼠标右键菜单
  15. 中安未来护照阅读器助力电子客票的推广和落实让你的出行说走就走
  16. 将US7ASCII 字符集的数据转到ZHS16GBK 字符集数据库
  17. EntityComponentSystemSamples学习笔记
  18. L1-020 帅到没朋友(C语言)
  19. Navicat12.1破 解教程,亲测可用
  20. 国内骨干网互联互通格局巨变,中移动将与电信和联通免费对等互联

热门文章

  1. 【JOURNAL】城邦组诗之十二 - 心肠
  2. ie在线邮件html编辑器,IE中HTML编辑器的修改与使用.doc
  3. java web 心跳机制实现,基于javax的websocket服务端实现,含心跳机制
  4. 脑细胞膜等效神经网路简单分类实例
  5. 我理解的 iOS 与 Android 的区别
  6. 转 plsql dev中Dynamic Performance Tables not accessible分析解决
  7. C语言 数据结构与算法 一
  8. Hello,Akka
  9. cpio.gz文件解压方法
  10. 构建一个分布式操作系统的简单方案—答陈硕的“分布式系统中的进程标识”一文...