diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/README.md" "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/README.md" index 05eb43f9ba5e8..6c0806543d256 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/README.md" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/README.md" @@ -39,16 +39,18 @@ -我们注意到,时间点最多只有 `24 * 60` 个,因此,当 timePoints 长度超过 `24 * 60`,说明有重复的时间点,提前返回 0。 +**方法一:排序** -接下来: +我们注意到,时间点最多只有 $24 \times 60$ 个,因此,当 $timePoints$ 长度超过 $24 \times 60$,说明有重复的时间点,提前返回 $0$。 -首先,遍历时间列表,将其转换为“分钟制”列表 `mins`,比如,对于时间点 `13:14`,将其转换为 `13 * 60 + 14`。 +接下来,我们首先遍历时间列表,将其转换为“分钟制”列表 $mins$,比如,对于时间点 `13:14`,将其转换为 $13 \times 60 + 14$。 -接着将“分钟制”列表按升序排列,然后将此列表的最小时间 `mins[0]` 加上 `24 * 60` 追加至列表尾部,用于处理最大值、最小值的差值这种特殊情况。 +接着将“分钟制”列表按升序排列,然后将此列表的最小时间 $mins[0]$ 加上 $24 \times 60$ 追加至列表尾部,用于处理最大值、最小值的差值这种特殊情况。 最后遍历“分钟制”列表,找出相邻两个时间的最小值即可。 +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为时间点个数。 + ### **Python3** @@ -62,10 +64,7 @@ class Solution: return 0 mins = sorted(int(t[:2]) * 60 + int(t[3:]) for t in timePoints) mins.append(mins[0] + 24 * 60) - res = mins[-1] - for i in range(1, len(mins)): - res = min(res, mins[i] - mins[i - 1]) - return res + return min(b - a for a, b in pairwise(mins)) ``` ### **Java** @@ -85,11 +84,11 @@ class Solution { } Collections.sort(mins); mins.add(mins.get(0) + 24 * 60); - int res = 24 * 60; + int ans = 1 << 30; for (int i = 1; i < mins.size(); ++i) { - res = Math.min(res, mins.get(i) - mins.get(i - 1)); + ans = Math.min(ans, mins.get(i) - mins.get(i - 1)); } - return res; + return ans; } } ``` @@ -100,17 +99,20 @@ class Solution { class Solution { public: int findMinDifference(vector& timePoints) { - if (timePoints.size() > 24 * 60) + if (timePoints.size() > 24 * 60) { return 0; + } vector mins; - for (auto t : timePoints) + for (auto& t : timePoints) { mins.push_back(stoi(t.substr(0, 2)) * 60 + stoi(t.substr(3))); + } sort(mins.begin(), mins.end()); mins.push_back(mins[0] + 24 * 60); - int res = 24 * 60; - for (int i = 1; i < mins.size(); ++i) - res = min(res, mins[i] - mins[i - 1]); - return res; + int ans = 1 << 30; + for (int i = 1; i < mins.size(); ++i) { + ans = min(ans, mins[i] - mins[i - 1]); + } + return ans; } }; ``` @@ -131,11 +133,11 @@ func findMinDifference(timePoints []string) int { } sort.Ints(mins) mins = append(mins, mins[0]+24*60) - res := 24 * 60 - for i := 1; i < len(mins); i++ { - res = min(res, mins[i]-mins[i-1]) + ans := 1 << 30 + for i, x := range mins[1:] { + ans = min(ans, x-mins[i]) } - return res + return ans } func min(a, b int) int { @@ -146,6 +148,27 @@ func min(a, b int) int { } ``` +### **TypeScript** + +```ts +function findMinDifference(timePoints: string[]): number { + if (timePoints.length > 24 * 60) { + return 0; + } + const mins: number[] = timePoints.map(timePoint => { + const [hour, minute] = timePoint.split(':').map(num => parseInt(num)); + return hour * 60 + minute; + }); + mins.sort((a, b) => a - b); + mins.push(mins[0] + 24 * 60); + let ans = 1 << 30; + for (let i = 1; i < mins.length; ++i) { + ans = Math.min(ans, mins[i] - mins[i - 1]); + } + return ans; +} +``` + ### **...** ``` diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.cpp" "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.cpp" index 16bf8b7636d04..33186886a2db1 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.cpp" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.cpp" @@ -1,16 +1,19 @@ -class Solution { -public: - int findMinDifference(vector& timePoints) { - if (timePoints.size() > 24 * 60) - return 0; - vector mins; - for (auto t : timePoints) - mins.push_back(stoi(t.substr(0, 2)) * 60 + stoi(t.substr(3))); - sort(mins.begin(), mins.end()); - mins.push_back(mins[0] + 24 * 60); - int res = 24 * 60; - for (int i = 1; i < mins.size(); ++i) - res = min(res, mins[i] - mins[i - 1]); - return res; - } +class Solution { +public: + int findMinDifference(vector& timePoints) { + if (timePoints.size() > 24 * 60) { + return 0; + } + vector mins; + for (auto& t : timePoints) { + mins.push_back(stoi(t.substr(0, 2)) * 60 + stoi(t.substr(3))); + } + sort(mins.begin(), mins.end()); + mins.push_back(mins[0] + 24 * 60); + int ans = 1 << 30; + for (int i = 1; i < mins.size(); ++i) { + ans = min(ans, mins[i] - mins[i - 1]); + } + return ans; + } }; \ No newline at end of file diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.go" "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.go" index b78b86aded154..afdca1977d3f6 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.go" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.go" @@ -11,11 +11,11 @@ func findMinDifference(timePoints []string) int { } sort.Ints(mins) mins = append(mins, mins[0]+24*60) - res := 24 * 60 - for i := 1; i < len(mins); i++ { - res = min(res, mins[i]-mins[i-1]) + ans := 1 << 30 + for i, x := range mins[1:] { + ans = min(ans, x-mins[i]) } - return res + return ans } func min(a, b int) int { diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.java" "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.java" index 388a86db391b4..379122a442254 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.java" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.java" @@ -1,19 +1,19 @@ -class Solution { - public int findMinDifference(List timePoints) { - if (timePoints.size() > 24 * 60) { - return 0; - } - List mins = new ArrayList<>(); - for (String t : timePoints) { - String[] time = t.split(":"); - mins.add(Integer.parseInt(time[0]) * 60 + Integer.parseInt(time[1])); - } - Collections.sort(mins); - mins.add(mins.get(0) + 24 * 60); - int res = 24 * 60; - for (int i = 1; i < mins.size(); ++i) { - res = Math.min(res, mins.get(i) - mins.get(i - 1)); - } - return res; - } +class Solution { + public int findMinDifference(List timePoints) { + if (timePoints.size() > 24 * 60) { + return 0; + } + List mins = new ArrayList<>(); + for (String t : timePoints) { + String[] time = t.split(":"); + mins.add(Integer.parseInt(time[0]) * 60 + Integer.parseInt(time[1])); + } + Collections.sort(mins); + mins.add(mins.get(0) + 24 * 60); + int ans = 1 << 30; + for (int i = 1; i < mins.size(); ++i) { + ans = Math.min(ans, mins.get(i) - mins.get(i - 1)); + } + return ans; + } } \ No newline at end of file diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.py" "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.py" index 09bc9167d7302..033a0c4769e12 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.py" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.py" @@ -1,10 +1,7 @@ -class Solution: - def findMinDifference(self, timePoints: List[str]) -> int: - if len(timePoints) > 24 * 60: - return 0 - mins = sorted(int(t[:2]) * 60 + int(t[3:]) for t in timePoints) - mins.append(mins[0] + 24 * 60) - res = mins[-1] - for i in range(1, len(mins)): - res = min(res, mins[i] - mins[i - 1]) - return res +class Solution: + def findMinDifference(self, timePoints: List[str]) -> int: + if len(timePoints) > 24 * 60: + return 0 + mins = sorted(int(t[:2]) * 60 + int(t[3:]) for t in timePoints) + mins.append(mins[0] + 24 * 60) + return min(b - a for a, b in pairwise(mins)) diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.ts" "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.ts" new file mode 100644 index 0000000000000..16870dba88e27 --- /dev/null +++ "b/lcof2/\345\211\221\346\214\207 Offer II 035. \346\234\200\345\260\217\346\227\266\351\227\264\345\267\256/Solution.ts" @@ -0,0 +1,16 @@ +function findMinDifference(timePoints: string[]): number { + if (timePoints.length > 24 * 60) { + return 0; + } + const mins: number[] = timePoints.map(timePoint => { + const [hour, minute] = timePoint.split(':').map(num => parseInt(num)); + return hour * 60 + minute; + }); + mins.sort((a, b) => a - b); + mins.push(mins[0] + 24 * 60); + let ans = 1 << 30; + for (let i = 1; i < mins.length; ++i) { + ans = Math.min(ans, mins[i] - mins[i - 1]); + } + return ans; +} diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/README.md" "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/README.md" index 5510c8c79e2fb..446ac50e6b53a 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/README.md" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/README.md" @@ -3,6 +3,7 @@ ## 题目描述 +

给定非负整数数组 heights ,数组中的数字用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1

求在该柱状图中,能够勾勒出来的矩形的最大面积。

 

@@ -26,48 +27,216 @@

 

注意:本题与主站 84 题相同: https://leetcode.cn/problems/largest-rectangle-in-histogram/

+ ## 解法 + + +**方法一:单调栈** + +单调栈常见模型:找出每个数左/右边**离它最近的**且**比它大/小的数**。模板: + +```python +stk = [] +for i in range(n): + while stk and check(stk[-1], i): + stk.pop() + stk.append(i) +``` + +枚举每根柱子的高度 $h$ 作为矩形的高度,向左右两边找第一个高度小于 $h$ 的下标 $left_i$, $right_i$。那么此时矩形面积为 $h \times (right_i-left_i-1)$,求最大值即可。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为柱子个数。 + + ### **Python3** + + ```python +class Solution: + def largestRectangleArea(self, heights: List[int]) -> int: + n = len(heights) + left = [-1] * n + right = [n] * n + stk = [] + for i, x in enumerate(heights): + while stk and heights[stk[-1]] >= x: + stk.pop() + if stk: + left[i] = stk[-1] + stk.append(i) + stk = [] + for i in range(n - 1, -1, -1): + while stk and heights[stk[-1]] >= heights[i]: + stk.pop() + if stk: + right[i] = stk[-1] + stk.append(i) + return max(x * (r - l - 1) for x, l, r in zip(heights, left, right)) +``` -```` ### **Java** + -```java -```` +```java +class Solution { + public int largestRectangleArea(int[] heights) { + int n = heights.length; + int[] left = new int[n]; + int[] right = new int[n]; + for (int i = 0; i < n; ++i) { + left[i] = -1; + right[i] = n; + } + Deque stk = new ArrayDeque<>(); + for (int i = 0; i < n; ++i) { + while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) { + stk.pop(); + } + if (!stk.isEmpty()) { + left[i] = stk.peek(); + } + stk.push(i); + } + stk.clear(); + for (int i = n - 1; i >= 0; --i) { + while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) { + stk.pop(); + } + if (!stk.isEmpty()) { + right[i] = stk.peek(); + } + stk.push(i); + } + int ans = 0; + for (int i = 0; i < n; ++i) { + ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]); + } + return ans; + } +} +``` ### **C++** -我们遍历每个柱体,若当前的柱体高度大于等于栈顶柱体的高度,就直接将当前柱体入栈,否则若当前的柱体高度小于栈顶柱体的高度,说明当前栈顶柱体找到了右边的第一个小于自身的柱体,那么就可以将栈顶柱体出栈来计算以其为高的矩形的面积了。 - ```cpp class Solution { public: int largestRectangleArea(vector& heights) { - int maxarea = 0; - stack s; - heights.insert(heights.begin(), 0); - heights.push_back(0); - - for (int i = 0; i < heights.size(); i++) { - while (!s.empty() && heights[i] < heights[s.top()]) { - int h = heights[s.top()]; - s.pop(); - maxarea = max(maxarea, h * (i - s.top() - 1)); + int n = heights.size(); + vector left(n, -1), right(n, n); + stack stk; + for (int i = 0; i < n; ++i) { + while (!stk.empty() && heights[stk.top()] >= heights[i]) { + stk.pop(); } - - s.push(i); + if (!stk.empty()) { + left[i] = stk.top(); + } + stk.push(i); } - - return maxarea; + stk = stack(); + for (int i = n - 1; ~i; --i) { + while (!stk.empty() && heights[stk.top()] >= heights[i]) { + stk.pop(); + } + if (!stk.empty()) { + right[i] = stk.top(); + } + stk.push(i); + } + int ans = 0; + for (int i = 0; i < n; ++i) { + ans = max(ans, (right[i] - left[i] - 1) * heights[i]); + } + return ans; } }; ``` +### **Go** + +```go +func largestRectangleArea(heights []int) (ans int) { + n := len(heights) + left := make([]int, n) + right := make([]int, n) + for i := range left { + left[i] = -1 + right[i] = n + } + stk := []int{} + for i, x := range heights { + for len(stk) > 0 && heights[stk[len(stk)-1]] >= x { + stk = stk[:len(stk)-1] + } + if len(stk) > 0 { + left[i] = stk[len(stk)-1] + } + stk = append(stk, i) + } + stk = []int{} + for i := n - 1; i >= 0; i-- { + for len(stk) > 0 && heights[stk[len(stk)-1]] >= heights[i] { + stk = stk[:len(stk)-1] + } + if len(stk) > 0 { + right[i] = stk[len(stk)-1] + } + stk = append(stk, i) + } + for i, x := range heights { + ans = max(ans, (right[i]-left[i]-1)*x) + } + return +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` + +### **TypeScript** + +```ts +function largestRectangleArea(heights: number[]): number { + const n = heights.length; + const left: number[] = new Array(n).fill(-1); + const right: number[] = new Array(n).fill(n); + const stk: number[] = []; + for (let i = 0; i < n; ++i) { + while (stk.length && heights[stk[stk.length - 1]] >= heights[i]) { + stk.pop(); + } + if (stk.length) { + left[i] = stk[stk.length - 1]; + } + stk.push(i); + } + stk.length = 0; + for (let i = n - 1; i >= 0; --i) { + while (stk.length && heights[stk[stk.length - 1]] >= heights[i]) { + stk.pop(); + } + if (stk.length) { + right[i] = stk[stk.length - 1]; + } + stk.push(i); + } + let ans = 0; + for (let i = 0; i < n; ++i) { + ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]); + } + return ans; +} +``` + ### **...** ``` diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.cpp" "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.cpp" index f379ee5097be3..bce9a75f56a37 100644 --- "a/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.cpp" +++ "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.cpp" @@ -1,21 +1,32 @@ class Solution { public: int largestRectangleArea(vector& heights) { - int maxarea = 0; - stack s; - heights.insert(heights.begin(), 0); - heights.push_back(0); - - for (int i = 0; i < heights.size(); i++) { - while (!s.empty() && heights[i] < heights[s.top()]) { - int h = heights[s.top()]; - s.pop(); - maxarea = max(maxarea, h * (i - s.top() - 1)); + int n = heights.size(); + vector left(n, -1), right(n, n); + stack stk; + for (int i = 0; i < n; ++i) { + while (!stk.empty() && heights[stk.top()] >= heights[i]) { + stk.pop(); } - - s.push(i); + if (!stk.empty()) { + left[i] = stk.top(); + } + stk.push(i); + } + stk = stack(); + for (int i = n - 1; ~i; --i) { + while (!stk.empty() && heights[stk.top()] >= heights[i]) { + stk.pop(); + } + if (!stk.empty()) { + right[i] = stk.top(); + } + stk.push(i); + } + int ans = 0; + for (int i = 0; i < n; ++i) { + ans = max(ans, (right[i] - left[i] - 1) * heights[i]); } - - return maxarea; + return ans; } }; \ No newline at end of file diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.go" "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.go" new file mode 100644 index 0000000000000..ec7e1d36cc520 --- /dev/null +++ "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.go" @@ -0,0 +1,40 @@ +func largestRectangleArea(heights []int) (ans int) { + n := len(heights) + left := make([]int, n) + right := make([]int, n) + for i := range left { + left[i] = -1 + right[i] = n + } + stk := []int{} + for i, x := range heights { + for len(stk) > 0 && heights[stk[len(stk)-1]] >= x { + stk = stk[:len(stk)-1] + } + if len(stk) > 0 { + left[i] = stk[len(stk)-1] + } + stk = append(stk, i) + } + stk = []int{} + for i := n - 1; i >= 0; i-- { + for len(stk) > 0 && heights[stk[len(stk)-1]] >= heights[i] { + stk = stk[:len(stk)-1] + } + if len(stk) > 0 { + right[i] = stk[len(stk)-1] + } + stk = append(stk, i) + } + for i, x := range heights { + ans = max(ans, (right[i]-left[i]-1)*x) + } + return +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} \ No newline at end of file diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.java" "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.java" new file mode 100644 index 0000000000000..d70aa3520938e --- /dev/null +++ "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.java" @@ -0,0 +1,36 @@ +class Solution { + public int largestRectangleArea(int[] heights) { + int n = heights.length; + int[] left = new int[n]; + int[] right = new int[n]; + for (int i = 0; i < n; ++i) { + left[i] = -1; + right[i] = n; + } + Deque stk = new ArrayDeque<>(); + for (int i = 0; i < n; ++i) { + while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) { + stk.pop(); + } + if (!stk.isEmpty()) { + left[i] = stk.peek(); + } + stk.push(i); + } + stk.clear(); + for (int i = n - 1; i >= 0; --i) { + while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) { + stk.pop(); + } + if (!stk.isEmpty()) { + right[i] = stk.peek(); + } + stk.push(i); + } + int ans = 0; + for (int i = 0; i < n; ++i) { + ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]); + } + return ans; + } +} \ No newline at end of file diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.py" "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.py" new file mode 100644 index 0000000000000..f124022a852af --- /dev/null +++ "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.py" @@ -0,0 +1,20 @@ +class Solution: + def largestRectangleArea(self, heights: List[int]) -> int: + n = len(heights) + left = [-1] * n + right = [n] * n + stk = [] + for i, x in enumerate(heights): + while stk and heights[stk[-1]] >= x: + stk.pop() + if stk: + left[i] = stk[-1] + stk.append(i) + stk = [] + for i in range(n - 1, -1, -1): + while stk and heights[stk[-1]] >= heights[i]: + stk.pop() + if stk: + right[i] = stk[-1] + stk.append(i) + return max(x * (r - l - 1) for x, l, r in zip(heights, left, right)) diff --git "a/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.ts" "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.ts" new file mode 100644 index 0000000000000..46c67a50ac440 --- /dev/null +++ "b/lcof2/\345\211\221\346\214\207 Offer II 039. \347\233\264\346\226\271\345\233\276\346\234\200\345\244\247\347\237\251\345\275\242\351\235\242\347\247\257/Solution.ts" @@ -0,0 +1,30 @@ +function largestRectangleArea(heights: number[]): number { + const n = heights.length; + const left: number[] = new Array(n).fill(-1); + const right: number[] = new Array(n).fill(n); + const stk: number[] = []; + for (let i = 0; i < n; ++i) { + while (stk.length && heights[stk[stk.length - 1]] >= heights[i]) { + stk.pop(); + } + if (stk.length) { + left[i] = stk[stk.length - 1]; + } + stk.push(i); + } + stk.length = 0; + for (let i = n - 1; i >= 0; --i) { + while (stk.length && heights[stk[stk.length - 1]] >= heights[i]) { + stk.pop(); + } + if (stk.length) { + right[i] = stk[stk.length - 1]; + } + stk.push(i); + } + let ans = 0; + for (let i = 0; i < n; ++i) { + ans = Math.max(ans, (right[i] - left[i] - 1) * heights[i]); + } + return ans; +}