在矩阵中寻找最大正方形连续区域
来源:互联网 发布:印度贫民窟 知乎 编辑:程序博客网 时间:2024/06/04 11:01
在矩阵中寻找最大正方形连续区域
问题描叙
输入一个矩阵M、一个数字k,找出一个最大的正方形连续区域,这个区域里的数字均是k。
界的思考
对于矩阵M中的每一个元素,要么等于k要么不等于k,要知道这个数的状态,必须有一次比较。一共n个数,所以至少需要
n2 次比较。故比较次数的下界为Ω(n2) ,那么是否存在一个O(n2) 的算法来解决这个问题呢?
算法
M中的每一个元素
Mij 都有一个与之对应的数值maxij 记录着以这个元素为左上角顶点的最大的一个正方形连续区域的大小(行/列 数)。
对元素Mij 有两种状态
Mij≠k , 此时可以得出maxij=0 。
Mij=k , 此时可以得出maxij=min(max(i+1)j,maxi(j+1),max(i+1)(j+1))+1 。
从右到左,从下往上地扫描矩阵M,计算出每一个元素的maxij ,其中最大的maxij 就是矩阵M的最大正方形连续区域的大小,其对应的元素的下标(i,j)就是这块连续区域的左上角顶点。
内存使用
大可不必创建
row×column 个空间来存储每一个元素的maxij ,实际上,在比较过程中只用min(row,column)+1 个内存空间就行了。
过程图示
例图:
第一轮循环:
第二轮循环:
第三轮循环:
用一个数据结构记录当前找到的最大的连续正方形的大小和对应的左上角坐标。
在比较的过程中,如果遇到更大的连续正方形,则更新记录。
代码
< header and helper >
#include<iostream>using namespace std;struct max_memo{//记录最大连续正方形区域的大小和左上角的坐标 //左上角的坐标 int row; int col; int num;//大小---以行or列为单位};//放回三个数中最小值。int min(int left, int down, int leftdown){ left = left < down ? left : down; return left < leftdown ? left : leftdown;}
< search >
void search(int M[][5],int k,int row,int col, max_memo &Max_memo){ int *memo = new int[row]; int up_one; int current; for (int i(0); i <row; i++){//初始化最后一行 if (M[col - 1][row - 1 - i] == k) memo[i] = 1; else memo[i] = 0; } Max_memo.col = col - 1, Max_memo.row = row - 1, Max_memo.num = memo[0];//初始化 int ex_index;//记录交换时的下标。 for (int row_local(row - 2), col_local(col - 1); row_local >= 0;)//外循环。 { col_local = (col - 1);//初始化列坐标---每次内循环从最右边开始,向左移动。 if (M[row_local][col_local] == k) { up_one = 1;//计算最右端的元素的最大连续区域(0 or 1) if (up_one > Max_memo.num){ Max_memo.col = col_local, Max_memo.row = row_local, Max_memo.num = up_one;//更新 } } else up_one = 0; col_local--; while (col_local >= 0){//内循环 ex_index = (col - 1) - col_local-1; if (M[row_local][col_local] != k){ current = 0; } if (M[row_local][col_local] == k){ current = min(up_one, memo[ex_index + 1], memo[ex_index]) + 1; if (current > Max_memo.num){ Max_memo.col = col_local, Max_memo.row = row_local, Max_memo.num = current;//更新 } } memo[ex_index] = up_one; up_one = current; col_local--;//向左移 } memo[row - 1] = up_one;//第一轮循环结束。 row_local--;//向上移 } delete[] memo;}
< main >
int main(){ int M[][5] = { /* { 0, 1, 1, 1, 1 }, { 0, 1, 2, 2, 1 }, { 1, 1, 2, 2, 1 }, { 1, 1, 2, 2, 1 }, { 1, 1, 0, 0, 1 } */ {0,0,0,0,1}, {0,0,0,0,1}, {0,0,0,0,1}, {0,0,0,0,1}, {0,0,0,0,0} }; max_memo Max_memo; int k = 1; search(M, k, 5, 5, Max_memo); if (Max_memo.num) cout << "结果: 坐标(" << Max_memo.row << ", " << Max_memo.col << "); 大小(以行为单位): " << Max_memo.num << endl; else cout << "没有值为"<<k<<"的连续正方形区域" << endl; cout << endl; system("pause");}
0 0
- 在矩阵中寻找最大正方形连续区域
- 01矩阵最大正方形
- 最大正方形子矩阵
- OpenCV图像中寻找最大区域Max_Area
- [LeetCode] 01矩阵中最大正方形 Maximal Square
- DP---求给定矩阵中最大正方形的维度
- 2163 最大正方形子矩阵
- 矩阵动归--最大正方形
- 寻找01矩阵中最大的子矩阵 Maximal Rectangle
- 华为机试 寻找最大正方形
- 【难】【DP】计算bool矩阵中,仅包含1的最大矩形和最大正方形
- wikioi 1259 最大正方形子矩阵
- vojos 1055,1057 最大子矩阵、正方形
- 0 1 矩阵查找最大正方形
- problem 11 矩阵中连续四个数的最大积
- 01二维矩阵中最大全为1的正方形maxSquare
- 在字符串中寻找连续最长的数字串
- 在数组中寻找连续子数组和最大值
- 数据结构与算法
- 复制文件
- iOS开发-时间日期NSDate
- 设计模式系列总结之观察者模式
- iOS推送本地通知 Push Notifications: local part
- 在矩阵中寻找最大正方形连续区域
- microsoft project 添加空行 空白行 空白任务
- 使用 matlab 数字图像处理(八)—— 画圆
- mac os x 设置终端快捷键
- hdu1241(dfs连通块)
- uva 11400 Lighting System Design
- shell编程学习2
- 【杭电-oj】-2032-杨辉三角
- 第8周项目4——游戏中的角色类增强版