[CTCI] 最大子方阵

最大子方阵

题目描述

有一个方阵,其中每个单元(像素)非黑即白(非0即1),请设计一个高效算法,找到四条边颜色相同的最大子方阵。

给定一个01方阵mat,同时给定方阵的边长n,请返回最大子方阵的边长。保证方阵变长小于等于100。

测试样例:

[[1,1,1],[1,0,1],[1,1,1]],3
返回:3

要看清题目,题目说的是四条边同一种颜色,不是四条边都是1。想法就是记录每个点右侧与下侧的连续0或1的个数,这样在给定一个左上角坐标与边长时,可以以O(1)的时间判断是否构成矩形。总的时候复杂度为O(N^3)。

 1 class SubMatrix {
 2 public:
 3     struct cell {
 4         int right, down;
 5         cell() : right(0), down(0){}
 6     };
 7     int maxSubMatrix(vector<vector<int> > mat, int n) {
 8         // write code here
 9         vector<vector<cell>> mmat1(n, vector<cell>(n));
10         vector<vector<cell>> mmat2(n, vector<cell>(n));
11         int tmp1, tmp2, res;
12         for (int i = n - 1; i >= 0; --i) {
13             for (int j = n - 1; j >= 0; --j) {
14                 if (j == n - 1) tmp1 = tmp2 = 0;
15                 else tmp1 = mmat1[i][j+1].right, tmp2 = mmat2[i][j+1].right;
16                 if (mat[i][j] == 1) mmat1[i][j].right = tmp1 + 1;
17                 else mmat2[i][j].right = tmp2 + 1;
18                 if (i == n - 1) tmp1 = tmp2 = 0;
19                 else tmp1 = mmat1[i+1][j].down, tmp2 = mmat2[i+1][j].down;
20                 if (mat[i][j] == 1) mmat1[i][j].down = tmp1 + 1;
21                 else mmat2[i][j].down = tmp2 + 1;
22             }
23         }
24         for (int i = n; i > 0; --i) {
25             if (isOK(mmat1, n, i) || isOK(mmat2, n, i)) return i;
26         }
27         return 0;
28     }
29     bool isOK(vector<vector<cell>> &mat, int n, int size) {
30         for (int i = 0; i <= n - size; ++i) {
31             for (int j = 0; j <= n - size; ++j) {
32                 if (isSquare(mat, i, j, size)) return true;
33             }
34         }
35         return false;
36     }
37     bool isSquare(vector<vector<cell>> &mat, int x, int y, int size) {
38         cell &lefttop = mat[x][y], &leftdown = mat[x+size-1][y], &righttop = mat[x][y+size-1];
39         if (lefttop.right < size) return false;
40         if (lefttop.down < size) return false;
41         if (leftdown.right < size) return false;
42         if (righttop.down < size) return false;
43         return true;
44     }
45 };
时间: 2024-10-21 08:53:12

[CTCI] 最大子方阵的相关文章

软件工程课程作业(四)--返回一个整数数组中最大子数组的和

伙伴链接:http://www.cnblogs.com/haoying1994/ 一.设计思想 本实验要求输入一个正负数混合的整型数组,长度不限,在此数组的所有子数组中找到和最大的数组,并求出相应数组的和,且时间复杂度为O(n).我们在课堂上共同讨论了多种解决方案,这些将在下面可能的解决方案中展示,在听了同学的思路和老师的讲解之后, 我们最终选取了老师课堂上描述的比较简便的思路.如下: 在输入数组的环节,采用for无限循环加if判断截止,直到触发回车键为止,将数组记录到Array中,数组长度记录

奇数阶魔方阵

原题 打印魔方阵,魔方阵是指这样的方针,每一行.每一列以及对角线的和相等.例如三阶魔方阵: 8 1 6 3 5 7 4 9 2 编程打印奇数阶魔方阵. 提示 问题解决的关键是元素的填充,第一个元素1的位置在第一行正中,新的位置应该处于最近插入元素的右上方:但如果右上方的位置超出方针上边界,则新的位置应该取列的最下一个位置:超出右边界则取行的最左的一个位置:若最近插入的元素为n的整数倍,则选下面一行同列上的位置为新的位置. 实现代码 /*******************************

求一个n阶方阵对角线元素之和

求一个n阶方阵对角线元素之和? public class shuixian { public static void main(String[] args) {  // TODO 自动生成的方法存根  int sum=0;  Scanner reader=new Scanner(System.in);  System.out.println("请输入方阵的阶数");  int n=reader.nextInt();  int[][] a=new int[n][n];  for(int

lincode.41 最大子数组

最大子数组 描述 笔记 数据 评测 给定一个整数数组,找到一个具有最大和的子数组,返回其最大和. 注意事项 子数组最少包含一个数 您在真实的面试中是否遇到过这个题? Yes 哪家公司问你的这个题? Airbnb Amazon LinkedIn Cryptic Studios Dropbox Apple Epic Systems TinyCo Yelp Hedvig Zenefits Uber Snapchat Yahoo Microsoft Bloomberg Facebook Google T

数据结构习题记录(1)——最大子列和问题

题目: 给定KK个整数组成的序列{ N_1N?1??, N_2N?2??, ..., N_KN?K?? },"连续子列"被定义为{ N_iN?i??, N_{i+1}N?i+1??, ..., N_jN?j?? },其中 1 \le i \le j \le K1≤i≤j≤K."最大子列和"则被定义为所有连续子列元素的和中最大者.例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20.现要求你编写程序,计

luogu 1101单词方阵

题目描述 给一nXn的字母方阵,内可能蕴含多个"yizhong"单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着8个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间[color=red]可以[/color]交叉,因此有可能共用字母.输出时,将不是单词的字母用"*"代替,以突出显示单词.例如: 输入: 8 输出: qyizhong *yizhong gydthkjy gy****** nwidghji n*i***** orbzsfgz o**z***

分治策略 &nbsp; 最大子数组问题

递归式 递归式与分治方法是紧密相关的,因为使用递归式可以很自然地刻画分治算法的运行时间.一个递归式就是一个等式或不等式,它通过更小的输入上的函数值来描述一个函数.例如,在2.3.2节,我们用递归式描述了MERGE-SORT过程的最坏情况运行时间T(n): Θ(1)        若n=1 T(n) =                         (4.1) 2T(n/2)+Θ(n)    若n>1 求解可得T(n)=Θ(nlgn) 递归式可以有很多形式.例如,一个递归算法可能将问题划分为规模

首尾相连求最大子数组和

题目要求: 1.输入一个一维整形数组,数组里有正数也有负数. 2.一维数组首尾相接,象个一条首尾相接带子一样. 3.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值. 设计思想: 遍历数组里面的每一个数将第一个数变为最后一个数,具体算法 a[i-1]=a[i],这样又变成了一个新的一维数组,输出每个数组的最大子数组和,然后比较每个输出的和,找出最大的数 代码: import java.util.Scanner; public class shuzu { p

最大子数组问题

小渣今天再来更新一波,欢迎看众 老爷们尽情喷(批评指导) 何为最大子数组:简言之,就是一数组A[n]中从i到j的连续子序列(i,j均在(0,n)区间内),且不存在另一对(a,b)对使得A[a]+A[a+1]+.....A[b]>A[i]+A[i+1]+...+A[j] 可见:①只有在数组含有负数元素时这个问题才有探讨的价值,否则整个数组本身即是最大子数组了: ②并且,i<=j(最大子数组可能只含有一个元素) ③最大子数组可能不唯一 思路:按照二分法来做,最大子数组两端无非有三种情况: 在左半部