2014-04-29 04:30

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

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

代码:

 // 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.
// I'll return the size and the left top corner of the subsquare.
#include <iostream>
#include <vector>
using namespace std; class Solution {
public:
void maxSubsquare(const vector<vector<int> > &matrix, int &max_left, int &max_top, int &max_size) {
int n = matrix.size(); max_left = max_top = max_size = -; if (n <= ) {
return;
} vector<vector<int> > top (n, vector<int>(n));
vector<vector<int> > bottom(n, vector<int>(n));
vector<vector<int> > left (n, vector<int>(n));
vector<vector<int> > right (n, vector<int>(n)); int i, j;
int tmp; // use DP to preprocess the data, count how many consecutive 1s are there to the left, right, top, bottom of matrix[i][j].
for (i = ; i <= n - ; ++i) {
tmp = ;
for (j = ; j <= n - ; ++j) {
left[i][j] = matrix[i][j] ? (++tmp) : (tmp = );
}
}
for (j = ; j <= n - ; ++j) {
tmp = ;
for (i = ; i <= n - ; ++i) {
top[i][j] = matrix[i][j] ? (++tmp) : (tmp = );
}
}
for (i = n - ; i >= ; --i) {
tmp = ;
for (j = n - ; j >= ; --j) {
right[i][j] = matrix[i][j] ? (++tmp) : (tmp = );
}
}
for (j = n - ; j >= ; --j) {
tmp = ;
for (i = n - ; i >= ; --i) {
bottom[i][j] = matrix[i][j] ? (++tmp) : (tmp = );
}
} int len;
// O(n ^ 3) solution with O(n ^ 2) space usage.
for (i = ; i < n; ++i) {
for (j = ; j < n; ++j) {
for (len = ; len + i <= n && len + j <= n; ++len) {
if (right[i][j] < len || bottom[i][j] < len) {
continue;
}
if (left[i][j + len - ] < len || bottom[i][j + len - ] < len) {
continue;
}
if (right[i + len - ][j] < len || top[i + len - ][j] < len) {
continue;
}
if (left[i + len - ][j + len - ] < len || top[i + len - ][j + len - ] < len) {
continue;
}
// all four borders are '1's.
if (len > max_size) {
max_top = i;
max_left = j;
max_size = len;
}
}
}
} // clear up data
for (i = ; i < n; ++i) {
left[i].clear();
right[i].clear();
top[i].clear();
bottom[i].clear();
}
left.clear();
right.clear();
top.clear();
bottom.clear();
};
}; int main()
{
int n;
int i, j;
vector<vector<int> > matrix;
Solution sol;
int max_left, max_top, max_size; while (cin >> n && n > ) {
matrix.resize(n);
for (i = ; i < n; ++i) {
matrix[i].resize(n);
} for (i = ; i < n; ++i) {
for (j = ; j < n; ++j) {
cin >> matrix[i][j];
}
} sol.maxSubsquare(matrix, max_left, max_top, max_size);
if (max_size > ) {
cout << max_top << ' ' << max_left << endl;
cout << max_top << ' ' << max_left + max_size - << endl;
cout << max_top + max_size - << ' ' << max_left << endl;
cout << max_top + max_size - << ' ' << max_left + max_size - << endl;
} else {
cout << "No subsquare found." << endl;
} for (i = ; i < n; ++i) {
matrix[i].clear();
}
matrix.clear();
} return ;
}

《Cracking the Coding Interview》——第18章:难题——题目11的更多相关文章

  1. Cracking the coding interview 第一章问题及解答

    Cracking the coding interview 第一章问题及解答 不管是不是要挪地方,面试题具有很好的联系代码总用,参加新工作的半年里,做的大多是探索性的工作,反而代码写得少了,不高兴,最 ...

  2. 《Cracking the Coding Interview》读书笔记

    <Cracking the Coding Interview>是适合硅谷技术面试的一本面试指南,因为题目分类清晰,风格比较靠谱,所以广受推崇. 以下是我的读书笔记,基本都是每章的课后习题解 ...

  3. Cracking the coding interview

    写在开头 最近忙于论文的开题等工作,还有阿里的实习笔试,被虐的还行,说还行是因为自己的水平或者说是自己准备的还没有达到他们所需要人才的水平,所以就想找一本面试的书<Cracking the co ...

  4. Cracking the coding interview目录及资料收集

    前言 <Cracking the coding interview>是一本被许多人极力推荐的程序员面试书籍, 详情可见:http://www.careercup.com/book. 第六版 ...

  5. Cracking the Coding Interview(Trees and Graphs)

    Cracking the Coding Interview(Trees and Graphs) 树和图的训练平时相对很少,还是要加强训练一些树和图的基础算法.自己对树节点的设计应该不是很合理,多多少少 ...

  6. Cracking the Coding Interview(Stacks and Queues)

    Cracking the Coding Interview(Stacks and Queues) 1.Describe how you could use a single array to impl ...

  7. 二刷Cracking the Coding Interview(CC150第五版)

    第18章---高度难题 1,-------另类加法.实现加法. 另类加法 参与人数:327时间限制:3秒空间限制:32768K 算法知识视频讲解 题目描述 请编写一个函数,将两个数字相加.不得使用+或 ...

  8. cracking the coding interview系列C#实现

    原版内容转自:CTCI面试系列——谷歌面试官经典作品 | 快课网 此系列为C#实现版本 谷歌面试官经典作品(CTCI)目录   1.1 判断一个字符串中的字符是否唯一 1.2 字符串翻转 1.3 去除 ...

  9. 《Cracking the Coding Interview》——第18章:难题——题目13

    2014-04-29 04:40 题目:给定一个字母组成的矩阵,和一个包含一堆单词的词典.请从矩阵中找出一个最大的子矩阵,使得从左到右每一行,从上到下每一列组成的单词都包含在词典中. 解法:O(n^3 ...

  10. 《Cracking the Coding Interview》——第18章:难题——题目12

    2014-04-29 04:36 题目:最大子数组和的二位扩展:最大子矩阵和. 解法:一个维度上进行枚举,复杂度O(n^2):另一个维度执行最大子数组和算法,复杂度O(n).总体时间复杂度为O(n^3 ...

随机推荐

  1. java——类加载机制

    类加载机制 JVM把class文件加载的内存,并对数据进行校验.转换解析和初始化,最终形成JVM可以直接使用的Java类型的过程就是加载机制. 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的生命 ...

  2. 【JavaScript 封装库】BETA 3.0 测试版发布!

    /* 源码作者: 石不易(Louis Shi) 联系方式: http://www.shibuyi.net =============================================== ...

  3. unixbench安装及使用

    unixbench 是一个用于測试 unix 系统性能的工具.也是一个比較通用的 benchmark, 此測试的目的是对类Unix 系统提供一个主要的性能指示,非常多測试用于系统性能的不同方面,这些測 ...

  4. 昂贵的聘礼,(最短路的应用),Poj(1063)

    题目链接:http://poj.org/problem?id=1062 很好的一道中文题. 思路: 把每种替换当做一条边,权重为交易优惠,就是求原点0到物品1的最短路. 这里有限制条件,每个节点还有等 ...

  5. Java继承和访问修饰符

    继承 概念:为了提取两个类中公共代码,可以使用继承抽取重复性的代码到一个公共类中,这个公共的类称为父类(super class).继承于父类的类称为子类(sub class). 关键字     ext ...

  6. Java从入门到放弃——04.数组

    本文目标 数组 1.数组 定义一个数组的三个姿势: 数组类型 []    数组名  =   new   数组类型[数组数量]: 数组类型 []    数组名  =   new   数组类型[]{对象1 ...

  7. redis 系列 在 vs上 set,get 键值

    1.启动两个 cmd,一个用于打开服务,一个用于运行客户端. 详细步骤可见上一篇文章 2.下载nuget的 ServiceStack.Redis;  ,并在using中引用 ,详细步骤可见上一篇文章 ...

  8. 在Linux文件清空的几种方法

    在Linux文件清空的几种方法 1.使用重定向的方法 [root@centos7 ~]# du -h test.txt 4.0K test.txt [root@centos7 ~]# > tes ...

  9. 泉五培训Day5

    T1 陪审团 题目 [题目描述] 陪审团制度历来是司法研究中的一个热议话题,由于陪审团的成员组成会对案件最终的结果产生巨大的影响,诉讼双方往往围绕陪审团由哪些人组成这一议题激烈争夺.小 W提出了一个甲 ...

  10. Maven - 配置镜像仓库

    默认仓库的配置(全球中央仓库): 可以打开maven的安装目录/conf/settings.xml文件,配置镜像,找到如下一段配置,这里默认没有配置任何镜像,但是有一个被注释的配置范例: id: 镜像 ...