[Swift]LeetCode84. 柱状图中最大的矩形 | Largest Rectangle in Histogram
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9935470.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]
.
The largest rectangle is shown in the shaded area, which has area = 10
unit.
Example:
Input: [2,1,5,6,2,3] Output: 10
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]
。
图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10
个单位。
示例:
输入: [2,1,5,6,2,3] 输出: 10
44ms
1 class Solution { 2 func largestRectangleArea(_ heights: [Int]) -> Int { 3 4 if heights.count == 0 { 5 return 0 6 } 7 8 if heights.count == 1 { 9 return heights[0] 10 } 11 var leftIndexes = Array<Int>.init(repeating: 0, count: heights.count) 12 var rightIndexes = Array<Int>.init(repeating: 0, count: heights.count) 13 leftIndexes[0] = -1 14 rightIndexes[heights.count - 1] = heights.count 15 16 for i in 1..<heights.count { 17 var p = i - 1 18 while p >= 0, heights[p] >= heights[i] { 19 p = leftIndexes[p] 20 } 21 leftIndexes[i] = p 22 } 23 24 for i in (0...heights.count - 2).reversed() { 25 var p = i + 1 26 while p < heights.count, heights[p] >= heights[i] { 27 p = rightIndexes[p] 28 } 29 rightIndexes[i] = p 30 } 31 var maxArea = 0 32 for i in 0..<heights.count { 33 maxArea = max(maxArea, heights[i] * (rightIndexes[i] - leftIndexes[i] - 1)) 34 } 35 36 return maxArea 37 } 38 }
64ms
1 class Solution { 2 func largestRectangleArea(_ heights: [Int]) -> Int { 3 4 let heights = heights + [0] 5 6 var indexStack: [Int] = [] 7 var maxHeight = 0 8 9 for (i,height) in heights.enumerated() { 10 11 while let previousIndex = indexStack.last, heights[previousIndex] > height { 12 indexStack.removeLast() 13 14 let lastIndex = indexStack.last ?? -1 15 let width = (i-1) - lastIndex 16 let height = heights[previousIndex] 17 18 maxHeight = max(maxHeight, width * height) 19 } 20 21 indexStack.append(i) 22 } 23 24 return maxHeight 25 } 26 }
72ms
1 class Solution { 2 func largestRectangleArea(_ heights: [Int]) -> Int { 3 4 var stack = [Int]() 5 var bestSolution = 0 6 var currentHeight = 0 7 8 for i in 0..<heights.count { 9 10 currentHeight = heights[i] 11 if currentHeight > bestSolution { 12 //bestSolution = currentHeight 13 } 14 15 while stack.last != nil && currentHeight <= heights[stack.last!] { 16 17 var lastIndex = stack.last! 18 var lastHeight = heights[lastIndex] 19 stack.removeLast() 20 21 var index = stack.isEmpty ? i : (i - 1 - stack.last!) 22 var rectHeight = lastHeight * (index) 23 24 if rectHeight > bestSolution { 25 bestSolution = rectHeight 26 } 27 } 28 29 stack.append(i) 30 } 31 32 while stack.last != nil { 33 34 var lastIndex = stack.last! 35 var lastHeight = heights[lastIndex] 36 stack.removeLast() 37 38 var index = stack.isEmpty ? (heights.count) : ((heights.count) - 1 - stack.last!) 39 var rectHeight = lastHeight * (index) 40 41 if rectHeight > bestSolution { 42 bestSolution = rectHeight 43 } 44 } 45 46 return bestSolution 47 } 48 }
76ms
1 class Solution { 2 func largestRectangleArea(_ heights: [Int]) -> Int { 3 4 if heights.count == 0 { 5 return 0 6 } 7 8 var myHeights: [Int] = heights 9 myHeights.append(0) 10 11 var s = 0 12 var stack: [Int] = [] 13 var i = 0 14 15 while i < myHeights.count { 16 17 if stack.count == 0 || myHeights[stack.last!] < myHeights[i] { 18 19 stack.append(i) 20 i += 1 21 } else { 22 23 let j = stack.last! 24 stack.removeLast() 25 26 s = max(s, myHeights[j]*(stack.isEmpty ? i : i - 1 - stack.last!)) 27 28 } 29 } 30 31 return s 32 } 33 }
88ms
1 class Solution { 2 func largestRectangleArea(_ heights: [Int]) -> Int { 3 var left: [Int] = Array(repeating: 0, count: heights.count) 4 var right: [Int] = Array(repeating: 0, count: heights.count) 5 var sums: [Int] = Array(repeating: 0, count: heights.count) 6 7 for index in 0..<heights.count { 8 var indexToLeft = index 9 while indexToLeft > 0 { 10 if heights[indexToLeft - 1] >= heights[index] { 11 indexToLeft -= 1 + left[indexToLeft-1] 12 } else { 13 break 14 } 15 } 16 17 left[index] = index-indexToLeft 18 } 19 20 for index in (0..<heights.count).reversed() { 21 var indexToRight = index 22 while (indexToRight + 1) < heights.count { 23 if heights[indexToRight + 1] >= heights[index] { 24 indexToRight += 1 + right[indexToRight+1] 25 } else { 26 break 27 } 28 } 29 30 right[index] = indexToRight - index 31 } 32 33 var maxSum = 0 34 for index in 0..<heights.count { 35 sums[index] = heights[index] * (left[index] + 1 + right[index]) 36 maxSum = max(maxSum, sums[index]) 37 } 38 return maxSum 39 } 40 }
96ms
1 class Solution { 2 func largestRectangleArea(_ heights: [Int]) -> Int { 3 var stack = [Int]() 4 var max = 0 5 for i in 0..<heights.count { 6 if stack.count == 0 || heights[i]>=heights[stack[stack.count-1]] { 7 stack.append(i) 8 } else { 9 while stack.count > 0 && heights[i] < heights[stack[stack.count-1]] { 10 let area = eval(&stack, heights, i) 11 if area > max { 12 max = area 13 } 14 } 15 stack.append(i) 16 } 17 } 18 while stack.count > 0 { 19 let area = eval(&stack, heights, heights.count) 20 if area > max { 21 max = area 22 } 23 } 24 return max 25 } 26 27 func eval(_ stack: inout [Int], _ heights: [Int], _ end: Int) -> Int { 28 let idx = stack.last! 29 stack.removeLast() 30 var area = 0 31 32 if let start = stack.last { 33 area = heights[idx]*(end-start-1) 34 } else { 35 area = heights[idx]*end 36 } 37 return area 38 } 39 }
148ms
1 class Solution { 2 func largestRectangleArea(_ heights: [Int]) -> Int { 3 if heights.isEmpty {return 0} 4 var stack = [0], maxArea = 0 5 var i = 1 6 while i < heights.count || !stack.isEmpty { 7 if i < heights.count && (stack.isEmpty || heights[i] >= heights[stack.last!]) { 8 stack.append(i) 9 i += 1 10 } else { 11 let curr = stack.popLast()! 12 let leftBound = stack.isEmpty ? -1 : stack.last! 13 let currArea = heights[curr] * (i - 1 - leftBound) 14 maxArea = max(maxArea, currArea) 15 } 16 } 17 return maxArea 18 } 19 }
236ms
1 class Solution { 2 func largestRectangleArea(_ heights: [Int]) -> Int { 3 var stack = [Int]() 4 var res = 0 5 for i in 0...heights.count { 6 let curr = i == heights.count ? 0 : heights[i] 7 while !stack.isEmpty && heights[stack[0]] > curr { 8 let height = heights[stack.removeFirst()] 9 let width = stack.isEmpty ? i : i - 1 - stack[0] 10 res = max(res, height * width) 11 } 12 stack.insert(i, at: 0) 13 } 14 return res 15 } 16 }