給定 n 個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度為 1 。求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。
第一種方法,我們先確定左右兩個邊界,然後找邊界中的最小值。比方說,我們左邊界確定為(0,2),右邊界確定為(4,2), 然後遍歷中間元素,發現最小值是(1,1),那麼面積就是(4-0) x 2 = 8
方法1
**如下
int min(int a, int b)
int max(int a, int b)
int largestrectanglearea(int* heights, int heightssize)
//計算面積
max_area = max(max_area, (j-i+1) * min_height);}}
return max_area;
}
我寫**時出錯的兩個地方
上面方法是固定左右邊界然後找中間的最小值,用到了三層迴圈,計算效率比較低。我們可以想辦法省掉第三層迴圈,比如說當我們計算完(0,2)-(2,5)內的最小值後,對於(0,2)-(3,6)的最小值,其實只要比較當前高度和之前的最小值,如果比前面的小,就更新最小值,否則就用之前的最小值。**如下
int largestrectanglearea(int* heights, int heightssize)
}return max_area;
}
或者我們可以換個思路,先把中間值固定住,然後找左右邊界。這裡的邊界指的是左右出現的第乙個比他小的棒子,比如說(1,1)就是最兩邊。
方法2
**如下
int largestrectanglearea(int* heights, int heightssize)
}for (int j = i; j >= 0; j--)
}max_area = max(max_area, (right_border-left_border) * heights[i]);
}return max_area;
}
依舊需要兩層迴圈,其中第二層迴圈的目的是就是找到左右邊界。那有沒有方法不需要用到迴圈就能找到左右的邊界呢?
思路和第二種方法類似,通過記錄已經出現的最小值來避免多餘計算,只不過這裡用棧處理,具體步驟為
如果比棧頂元素小
遍歷結束後,清空棧
我們以最特殊的兩個資料來舉例,對於[0,1,2,3,4,5,6,7], 每乙個元素都比之前的小,那麼每個元素入棧的時候,我們都只能確定它的左邊界,也就是它的上乙個元素,而無法確定它的右邊界,比如說(1,1)的左邊界就是(0,0), 而右邊的位置必須等到所有元素都入棧之後才能確定,最後算出來的面積是(8-1)x1=7.
方法3-1
對於[7,6,5,4,3,2,1,0], 我們先入棧(0,7),然**棧(1,6), 此時對於高度為7的棒子而言,它已經到頭了,面積只肯能是7. 一波操作之後,棧內部元素為(1,6), 此時來了(2,5), 那麼6也到頭了,它的面積就是(1-(-1) x 6 = 12.,其中-1棧初始後第乙個元素。
最終**如下(大部分**是實現棧的操作)
int max(int a, int b)
typedef struct stack;
stack *create(int k)
void push(stack *st, int val)
int peek(stack *st)
int pop(stack *st)
void destroy(stack *st)
int largestrectanglearea(int* heights, int heightssize)
push(st, i);
}while ( peek(st) != -1)
destroy(st);
return max_area;
}
我寫**出錯的兩個地方
方法3-2
最終借用額外到資料結構,時間複雜度從原來的o(n^3)優化到最後到o(n), 也就是利用空間換取了時間。
LeetCode 695島嶼最大面積
給定乙個包含了一些 0 和 1 的非空二維陣列 grid 乙個 島嶼 是由一些相鄰的 1 代表土地 構成的組合,這裡的 相鄰 要求兩個 1 必須在水平或者豎直方向上相鄰。你可以假設 grid 的四個邊緣都被 0 代表水 包圍著。找到給定的二維陣列中最大的島嶼面積。如果沒有島嶼,則返回面積為 0 示例...
最大面積問題 LargestReactangle
描述 在下列非負陣列中找出最大面積 heigh 0,2,1,3,4,3,2,0 若干非負陣列組成面積不同的矩形,求上述中的最大面積。在圖中畫出了下標 3 5 高度為3,面積為9的矩形和下標為 1 6 高度為1面積為6的矩形。思路 暴力遍歷 1 從下標i開始,對於每乙個高度heigh i h,向左遍歷...
10 18 最大面積 2432
學過初三數學或圓的相關知識的人都會求陰影部分面積。垂徑定理和勾股定理 s陰 a r2 1 2 a 2 b r 2 1 2 b 2 a b 然後就可以列舉a,b找最大值 a,b 2r var r,a,b,i,j longint c,max,b1,a1 double begin readln r for...