LeetCode
84. 柱狀圖中最大的矩形
這道題的思路很明确,首先周遊整個數組,找到數值最小元素的位置和值,那麼包含這個位置的矩形的最大高度隻能是這個最小值,矩形的寬度最大為整個數組的長度,能夠存在的更大的矩形隻能是不包含這個位置的其他矩形,即在最小位置的左側和右側分别進行以上操作,直到數組邊界位置,用遞歸來解決,不斷松弛最大矩形的面積。
參考快速排序的時間複雜度,算法時間複雜度為O(nlogn).
class Solution {
public:
void dfs(vector<int>& heights,int &ans,int l,int r)
{
int minn=-1,minid=1;
for(int i=l;i<=r;i++)
{
if(minn==-1)
{
minn=heights[i];
minid=i;
}
if(minn>heights[i])
{
minn=heights[i];
minid=i;
}
}
ans=max(ans,minn*(r-l+1));
if(minid-1>=l)dfs(heights,ans,l,minid-1);
if(minid+1<=r)dfs(heights,ans,minid+1,r);
return;
}
int largestRectangleArea(vector<int>& heights) {
int n=heights.size();
int ans=0;
if(n==0)return ans;
int l=0,r=n-1;
int minn=-1,minid=-1;
for(int i=0;i<n;i++)
{
if(minn==-1)
{
minn=heights[i];
minid=i;
}
if(minn>heights[i])
{
minn=heights[i];
minid=i;
}
}
ans=max(ans,minn*(r-l+1));
if(minid-1>=0)dfs(heights,ans,l,minid-1);
if(minid+1<n)dfs(heights,ans,minid+1,r);
return ans;
}
};
85. 最大矩形
這道題需要進行一個預處理,首先從倒數第二行開始直到第一行,如果matrix[i][j]=1,那麼matrix[i][j]+=matrix[i+1][j],即通過o(nm)的預處理來獲得每個位置及其下方連續的1的個數,預處理完之後我們可以發現,每一行都形成了上一題中的柱狀圖數組,那麼調用n次柱狀圖數組即可求得最大面積。
算法的時間複雜度為O(nmlog(m))
class Solution {
public:
void dfs(vector<int>& heights,int &ans,int l,int r)
{
int minn=-1,minid=1;
for(int i=l;i<=r;i++)
{
if(minn==-1)
{
minn=heights[i];
minid=i;
}
if(minn>heights[i])
{
minn=heights[i];
minid=i;
}
}
ans=max(ans,minn*(r-l+1));
if(minid-1>=l)dfs(heights,ans,l,minid-1);
if(minid+1<=r)dfs(heights,ans,minid+1,r);
return;
}
int largestRectangleArea(vector<int>& heights) {
int n=heights.size();
int ans=0;
if(n==0)return ans;
int l=0,r=n-1;
int minn=-1,minid=-1;
for(int i=0;i<n;i++)
{
if(minn==-1)
{
minn=heights[i];
minid=i;
}
if(minn>heights[i])
{
minn=heights[i];
minid=i;
}
}
ans=max(ans,minn*(r-l+1));
if(minid-1>=0)dfs(heights,ans,l,minid-1);
if(minid+1<n)dfs(heights,ans,minid+1,r);
return ans;
}
int maximalRectangle(vector<vector<char>>& matrix1) {
int n=matrix1.size();
if(n==0)return 0;
int ans=0;
int m=matrix1[0].size();
vector<vector<int>> matrix(n);
for(int i=0;i<n;i++)matrix[i].resize(m);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
matrix[i][j]+=matrix1[i][j]-'0';
}
}
for(int i=n-1;i>=0;i--)
{
for(int j=0;j<m;j++)
{
if(i==n-1)break;
if(matrix[i][j]==1)
{
matrix[i][j]+=matrix[i+1][j];
}
}
}
for(int i=0;i<n;i++)
{
ans=max(ans,largestRectangleArea(matrix[i]));
}
return ans;
}
};
221. 最大正方形
這道題同上題一樣進行預處理,不同之處在于答案的更新上,在更新ans之前比較目前矩形高度和長度的關系,如果高度大于長度,那麼跳出遞歸(因為後續的高度肯定高于目前高度,後續寬度肯定小于目前寬度,也就是說後續肯定無解),如果高度小于等于長度,那麼ans=minheight*minheight,其他同上題一樣。
算法的時間複雜度為O(nmlog(m))
class Solution {
public:
void dfs(vector<int>& heights,int &ans,int l,int r)
{
int minn=-1,minid=1;
for(int i=l;i<=r;i++)
{
if(minn==-1)
{
minn=heights[i];
minid=i;
}
if(minn>heights[i])
{
minn=heights[i];
minid=i;
}
}
if(minn<=r-l+1)ans=max(ans,minn*minn);
else return;
if(minid-1>=l)dfs(heights,ans,l,minid-1);
if(minid+1<=r)dfs(heights,ans,minid+1,r);
return;
}
int largestRectangleArea(vector<int>& heights) {
int n=heights.size();
int ans=0;
if(n==0)return ans;
int l=0,r=n-1;
int minn=-1,minid=-1;
for(int i=0;i<n;i++)
{
if(minn==-1)
{
minn=heights[i];
minid=i;
}
if(minn>heights[i])
{
minn=heights[i];
minid=i;
}
}
if(minn<=r-l+1)ans=max(ans,minn*minn);
else return 0;
if(minid-1>=0)dfs(heights,ans,l,minid-1);
if(minid+1<n)dfs(heights,ans,minid+1,r);
return ans;
}
int maximalSquare(vector<vector<char>>& matrix1) {
int n=matrix1.size();
if(n==0)return 0;
int ans=0;
int m=matrix1[0].size();
vector<vector<int>> matrix(n);
for(int i=0;i<n;i++)matrix[i].resize(m);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
matrix[i][j]+=matrix1[i][j]-'0';
}
}
for(int i=n-1;i>=0;i--)
{
for(int j=0;j<m;j++)
{
if(i==n-1)break;
if(matrix[i][j]==1)
{
matrix[i][j]+=matrix[i+1][j];
}
}
}
for(int i=0;i<n;i++)
{
ans=max(ans,largestRectangleArea(matrix[i]));
}
return ans;
}
};