Algorithm leetcode|84. The largest rectangle in the histogram (rust hits hard)



84. The largest rectangle in the histogram:

Given n non-negative integers, used to represent the height of each column in the histogram. Each column is adjacent to each other and has width 1 .

Find the maximum area of ​​the rectangle that can be drawn in this histogram.

Example 1:

输入:

	heights = [2,1,5,6,2,3]
	
输出:
	
	10
	
解释:
	
	最大的矩形为图中红色区域,面积为 10

Example 2:

输入:
	
	 heights = [2,4]
	 
输出: 
	
	4

hint:

  • 1 <= heights.length <=105
  • 0 <= heights[i] <= 104

analyze:

  • Facing this algorithm question, the second master once again fell into deep thought.
  • At first glance, there seems to be an idea, but once you start doing it, it's easy to not know where to start.
  • Double loop, traverse each column, find the first column on the left that is lower than itself, and the first column on the right that is lower than itself. In this way, you can calculate the maximum width of the height of the current column. If you have a clue, it will obviously be very Wait, is there a better way?
  • Finding the left and right boundaries of each column (the first column lower than itself) is the key. Is there any way to reduce the complexity of the search?
  • It would be great if we could find the left and right boundaries in one traversal. Use the artifact monotonic stack. If the stack is empty, push it into the stack (you can use techniques here to unify the processing logic). Otherwise, judge whether the next pillar is higher than the top of the stack or equal to the top of the stack. If the top of the stack is the same height, it will be pushed directly into the stack. If it is lower than the top of the stack, it will be popped out of the stack, because the current column is the right boundary of the top element of the stack. Repeat this process, and you can find the left and right boundaries in one traversal.
  • Pay special attention to the situation when the stack is empty during the traversal process, and when all columns are traversed but the stack is not empty.

answer:

rust:

impl Solution {
    
    
    pub fn largest_rectangle_area(heights: Vec<i32>) -> i32 {
    
    
        let mut ans = 0;

        let mut stack = vec![-1];
        let n = heights.len();
        (0..n).for_each(|i| {
    
    
            while stack.len() > 1 && heights[*stack.last().unwrap() as usize] > heights[i] {
    
    
                // 栈中比当前位置高的那些待确定右边界的下标都可以确定右边界了

                ans = ans.max(heights[stack.pop().unwrap() as usize] * (i as i32 - 1 - stack.last().unwrap()));
            }
            // 入栈,等到能够确定右边界时处理
            stack.push(i as i32);
        });

        while stack.len() > 1 {
    
    
            // 栈中剩余的都是右边没有更低的

            ans = ans.max(heights[stack.pop().unwrap() as usize] * (n as i32 - 1 - stack.last().unwrap()));
        }

        return ans;
    }
}

go:

func largestRectangleArea(heights []int) int {
    
    
    max := func(x, y int) int {
    
    
		if x > y {
    
    
			return x
		}
		return y
	}

	ans := 0

	n := len(heights)
	stack := []int{
    
    -1}
	for i := 0; i < n; i++ {
    
    
		for len(stack) > 1 && heights[stack[len(stack)-1]] > heights[i] {
    
    
			// 栈中比当前位置高的那些待确定右边界的下标都可以确定右边界了

			ans = max(ans, heights[stack[len(stack)-1]]*(i-1-stack[len(stack)-2]))
			// 出栈
			stack = stack[:len(stack)-1]
		}
		// 入栈,等到能够确定右边界时处理
		stack = append(stack, i)
	}

	for len(stack) > 1 {
    
    
		// 栈中剩余的都是右边没有更低的

		ans = max(ans, heights[stack[len(stack)-1]]*(n-1-stack[len(stack)-2]))
		// 出栈
		stack = stack[:len(stack)-1]
	}

	return ans
}

c++:

class Solution {
    
    
public:
    int largestRectangleArea(vector<int>& heights) {
    
    
        int ans = 0;

        const int n = heights.size();
        stack<int> s;
        s.push(-1);
        for (int i = 0; i < n; ++i) {
    
    
            while (s.size() > 1 && heights[s.top()] > heights[i]) {
    
    
                // 栈中比当前位置高的那些待确定右边界的下标都可以确定右边界了

                int height = heights[s.top()];
                s.pop();
                ans = max(ans, height * (i - 1 - s.top()));
            }
            // 入栈,等到能够确定右边界时处理
            s.push(i);
        }

        while (s.size() > 1) {
    
    
            // 栈中剩余的都是右边没有更低的

            int height = heights[s.top()];
            s.pop();
            ans = max(ans, height * (n - 1 - s.top()));
        }

        return ans;
    }
};

python:

class Solution:
    def largestRectangleArea(self, heights: List[int]) -> int:
        ans = 0

        n = len(heights)
        stack = [-1]
        for i in range(n):
            while len(stack) > 1 and heights[stack[-1]] > heights[i]:
                # 比当前位置高的那些待确定右边界的下标都可以确定右边界了
                ans = max(ans, heights[stack.pop()] * (i - 1 - stack[-1]))
            # 入栈,等到能够确定右边界时处理
            stack.append(i)
        while len(stack) > 1:
            # 栈中剩余的都是右边没有更低的
            ans = max(ans, heights[stack.pop()] * (n - 1 - stack[-1]))

        return ans


java:

class Solution {
    
    
    public int largestRectangleArea(int[] heights) {
    
    
        int ans = 0;

        final int      n     = heights.length;
        Deque<Integer> stack = new LinkedList<>();
        stack.push(-1);
        for (int i = 0; i < n; ++i) {
    
    
            while (stack.size() > 1 && heights[stack.peek()] > heights[i]) {
    
    
                // 栈中比当前位置高的那些待确定右边界的下标都可以确定右边界了

                ans = Math.max(ans, heights[stack.pop()] * (i - 1 - stack.peek()));
            }
            // 入栈,等到能够确定右边界时处理
            stack.push(i);
        }

        while (stack.size() > 1) {
    
    
            // 栈中剩余的都是右边没有更低的

            ans = Math.max(ans, heights[stack.pop()] * (n - 1 - stack.peek()));
        }

        return ans;
    }
}

Thank you very much for reading this article~
Welcome [Like] [Collect] [Comment] Three times in a row~
It is not difficult to give up. But perseverance must be cool~
I hope we can all make a little progress every day~
This article is written by the white hat of the second boss: https://le-yi.blog.csdn.net/ Original blog~


Guess you like

Origin blog.csdn.net/leyi520/article/details/133166907