本文概述
- CPP
- python
例子:
输入:mat [] [] = {{1, 2, 3}, {4, 5, 6}, {1, 2, 3}}方法:有许多方法来解决这个问题,从O(N^3 * M^3)到O(N * M).在这篇文章中,将讨论一个O(N * M)时间复杂度的方法使用堆栈。
输出:6
最大的子矩阵将是{{1, 2, 3} , {4, 5, 6}}。此子矩阵中的元素数=6。
输入:mat [] [] = {{1, 2, 3}, {4, 5, 3}, {1, 2, 3}}
输出:4
最大的子-matrix将为{{1, 2}, {4, 5}}
让我们试着从广义上理解这种方法,然后讨论算法。对于矩阵的每一列,试着找到左边在这一列的最大的行排序和列排序子矩阵。为了执行同样的操作,创建一个矩阵pre[][],其中pre[i][j]将存储从数组arr[i]的索引j开始最长的递增子数组的长度。
现在使用这个矩阵,对于每一列j,求出最长的行排序和列排序数组的长度。要处理一列,需要数组pre[][j]中所有不断增加的子段。使用两个指针技术也可以找到相同的结果。在每一个子区段中,只需找到直方图下最大的区域,将逐行递增的子区段视为条形图。
- 为每行" i"创建一个前缀和数组, 该数组存储以该行的每一列" j"结尾的最大递增子数组的长度。
- 一旦有了这个数组, 对于每一列" j"。
- 初始化" i"等于0。
- 在" i"小于" N"时在" i"上循环
- 初始化" k"等于i + 1。
- 当k小于N且arr [k] [j]大于arr [k-1] [j]时, 递增k。
- 在子数组pre [i] [j]到pre [k-1] [j]上应用直方图问题, 以找到其下的最大面积。让我们将此值称为" V"。将最终答案更新为ans = max(ans, val)。
- 更新" i"等于k-1。
CPP
//C++ implementation of the approach
#include <
bits/stdc++.h>
using namespace std;
//Function to return the largest
//area under a histogram
int histo(vector<
int>
q)
{//Stack
stack<
int>
q1;
//Length of the vector
int n = q.size();
//Function to store the next smaller
//and previous smaller index
int pre_smaller[q.size()];
int next_smaller[q.size()];
//Finding the next smaller
for ( int i = 0;
i <
n;
i++)
pre_smaller[i] = -1, next_smaller[i] = n;
for ( int i = 0;
i <
n;
i++) {
while (q1.size() and q[q1.top()]>
q[i]) {
next_smaller[q1.top()] = i;
q1.pop();
}
q1.push(i);
}//Finding the previous smaller element
while (q1.size())
q1.pop();
for ( int i = n - 1;
i>
= 0;
i--) {
while (q1.size() and q[q1.top()]>
q[i]) {
pre_smaller[q1.top()] = i;
q1.pop();
}
q1.push(i);
}//To store the final answer
int ans = 0;
//Finding the final answer
for ( int i = 0;
i <
n;
i++)
ans = max(ans, (next_smaller[i]
- pre_smaller[i] - 1)
* q[i]);
//Returning the final answer
return ans;
}//Function to return the largest area
//for the requried submatrix
int findLargest(vector<
vector<
int>
>
arr)
{
//n and m store the number of
//rows and columns respectively
int n = arr.size();
int m = arr[0].size();
//To store the prefix_sum
int pre[n][m];
//To store the final answer
int ans = 0;
//Loop to create the prefix-sum
//using two pointers
for ( int i = 0;
i <
n;
i++)
for ( int j = 0;
j <
m;
j++) {
if (j == 0) {
pre[i][j] = 1;
continue ;
}
if (arr[i][j]>
arr[i][j - 1])
pre[i][j] = pre[i][j - 1] + 1;
else
pre[i][j] = 1;
}//For each column run the loop
for ( int j = 0;
j <
m;
j++) {//Find the largest row-wise sorted arrays
for ( int i = 0;
i <
n;
i++) {
int k = i + 1;
vector<
int>
q;
q.push_back(pre[i][j]);
while (k <
n and arr[k]>
arr[k - 1])
q.push_back(pre[k][j]), k++;
//Applying the largest area
//under the histogram
ans = max(ans, histo(q));
i = k - 1;
}
}//Return the final answer
return ans;
}//Driver code
int main()
{
vector<
vector<
int>
>
arr = { { 1, 2, 3 }, { 4, 5, 6 }, { 1, 2, 3 } };
cout <
<
findLargest(arr);
return 0;
}
python
# Pythono3 implementation of the approach# Function to return the largest
# area under a histogram
def histo(q):# Stack
q1 = []# Length of the vector
n = len (q)# Function to store the next smaller
# and previous smaller index
pre_smaller = [ 0 for i in range ( len (q))]
next_smaller = [ 0 for i in range ( len (q))]# Finding the next smaller
for i in range (n):
pre_smaller[i] = - 1
next_smaller[i] = n
for i in range (n):
while ( len (q1)>
0 and q[q1[ - 1 ]]>
q[i]):
next_smaller[q1[ - 1 ]] = i
del q1[ - 1 ]
q1.append(i)# Finding the previous smaller element
while ( len (q1)>
0 ):
del q1[ - 1 ]for i in range (n - 1 , - 1 , - 1 ):
while ( len (q1)>
0 and q[q1[ - 1 ]]>
q[i]):
pre_smaller[q1[ - 1 ]] = i
del q1[ - 1 ]q1.append(i)# To store the final answer
ans = 0# Finding the final answer
for i in range (n):
ans = max (ans, (next_smaller[i] - pre_smaller[i] - 1 ) * q[i])# Returning the final answer
return ans# Function to return the largest area
# for the requried submatrix
def findLargest(arr):# n and m store the number of
# rows and columns respectively
n = len (arr)
m = len (arr[ 0 ])# To store the prefix_sum
pre = [[ 0 for i in range (m)] for i in range (n)]# To store the final answer
ans = 0# Loop to create the prefix-sum
# using two pointers
for i in range (n):
for j in range (m):
if (j = = 0 ):
pre[i][j] = 1
continueif (arr[i][j]>
arr[i][j - 1 ]):
pre[i][j] = pre[i][j - 1 ] + 1
else :
pre[i][j] = 1# For each column run the loop
for j in range (m):# Find the largest row-wise sorted arrays
for i in range (n):
k = i + 1
q = []
q.append(pre[i][j])
while (k <
n and arr[k]>
arr[k - 1 ]):
q.append(pre[k][j])
k + = 1# Applying the largest area
# under the histogram
ans = max (ans, histo(q))
i = k - 1# Return the final answer
return ans# Driver codearr = [ [ 1 , 2 , 3 ], [ 4 , 5 , 6 ], [ 1 , 2 , 3 ] ]print (findLargest(arr))# This code is contributed by mohit kumar 29
输出如下:
6
【算法题(最大的按行和按列排序的子矩阵)】时间复杂度:O(N^2)
推荐阅读
- 硬实时和软实时系统之间有什么区别()
- u盘打开盘自制,教您如何迅速自制一个PE系统
- u盘装系统工具,教您u盘怎样安装win7系统
- 7彩虹u盘打开,教您7彩虹主板怎样设置u盘打开
- 昂达u盘打开,教您昂达主板BIOS怎样设置u盘打开
- usb鼠标接触不良,教您usb鼠标接触不良
- U盘系统_教您将系统安装到U盘
- u盘打开读不了硬盘,教您U盘装系统找不到硬盘处理办法
- u盘扩大内存,教您如何用U盘扩展内存