[Data structure] LeetCode questions of the stack: 20. Effective brackets, 155. The smallest stack, 84. The largest rectangle of the histogram

20. Effective brackets¹

Includes only a given '(', ')', '{', '}', '[', ']'string, determines whether the string is valid.

A valid string must meet:

  1. The left parenthesis must be closed with the same type of right parenthesis.
  2. The opening parenthesis must be closed in the correct order.

Note that an empty string can be considered a valid string.

Example 1:

输入: "()"
输出: true

Example 2:

输入: "()[]{}"
输出: true

Example 3:

输入: "(]"
输出: false

Example 4:

输入: "([)]"
输出: false

Example 5:

输入: "{[]}"
输出: true

Solution one: stack (thinking one)

This idea is very simple and straightforward, that is, push all the left half (,[,{ onto the stack, and match the right half one by one.

public boolean isValid(String s) {
    
    
       Stack<Character> stack = new Stack<>();
       for (char c : s.toCharArray()) {
    
    
            if (c == '(' || c == '[' || c == '{') 
                stack.push(c);
           // 当右括号匹配上了出栈
           // 注:isEmpty判断很关键
            else if (c == ')' && !stack.isEmpty() && stack.peek() == '(' ) 
                stack.pop();
            else if (c == ']' && !stack.isEmpty() && stack.peek() == '[' ) 
                stack.pop();
            else if (c == '}' && !stack.isEmpty() && stack.peek() == '{' ) 
                stack.pop();
            else 
                // 右括号匹配不上,返回false
                return false;
       }
       // ")))))"
       return stack.isEmpty();
}

Solution two: stack (thinking two)

This kind of thinking is that the left half is pushed into the stack, but it is (into the stack), [into the stack], {into the stack}, and the other half is compared for equality. It may sound obscure, but the code can be understood at a glance:

¹public boolean isValid(String s) {
    
    
        Stack<Character> stack = new Stack<>();
        for(char c : s.toCharArray()) {
    
    
            if(c == '(')
                stack.push(')');
            else if(c == '{') 
                stack.push('}');
            else if(c == '[')
                stack.push(']');
            else if(stack.isEmpty() || stack.pop() != c) // 这里比较的是是否相等
                return false;
        }

        return stack.isEmpty();
}

Compared to Idea 1, the code of this solution is cleaner.

155. Minimum stack¹ (maintain minimum)

Design a stack that supports push, pop, and top operations and can retrieve the smallest element in a constant time.

  • push(x)-Push element x onto the stack.
  • pop()-Remove the element at the top of the stack.
  • top()-Get the top element of the stack.
  • getMin()-Retrieve the smallest element in the stack.

Example:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.getMin();   --> 返回 -2.

Solution one: auxiliary stack

First of all, we must understand that there are no special requirements, so we can directly use the stack provided by jdk , that is, we don't need to implement a stack ourselves, just solve the problem of how to find the minimum value.

The solution is to create another auxiliary stack to save the minimum value after each push/pop operation.

class MinStack {
    
    
	
    // 保存按序放入数据的栈,直接使用jdk的栈就行
    Stack<Integer> items;
    // 保存最小值的栈
    Stack<Integer> min;

    public MinStack() {
    
    
        this.items = new Stack<>();
        this.min = new Stack<>();
    }
    
    public void push(int x) {
    
    
        // 自动装箱
        items.push(x);
        // 注:一定要先判断,栈空的就直接放入
        if (min.isEmpty())  
            min.push(x);
        // !注:这里的<=,必须等于也要入栈,不然到时候相等的值就存一个,出栈后就错了
        else if(x <= min.peek()) 
            min.push(x);
    }
    
    public void pop() {
    
    
        // !!注:一定要intValue取出int,不然自动装箱在-127-128外的值地址不一样,肯定false
        // 如 item-push:-128(addr1)min-push:-128(addr2)
         if (min.peek() == items.pop().intValue()) 
            min.pop();
    }
    
    public int top() {
    
    
        return items.peek();
    }
    
    public int getMin() {
    
    
        return min.peek();
    }
}

84. The largest rectangle in the histogram³

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

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

img

The above is an example of a histogram, where the width of each column is 1, and the given height is [2,1,5,6,2,3].

img

The shaded portion is the maximum that can be outlined by a rectangular area, which area 10units.

Example:

输入: [2,1,5,6,2,3]
输出: 10

Solution 1: Enumeration

  • Idea: The area of ​​a rectangle is nothing more than length by width, so we can enumerate all the length and width conditions, and then find the maximum area. When implemented in the code, the combination of all two pillars is enumerated, which is obviously a two-layer loop.
  • the complexity
    • Time : O (n ^ 2)
    • Space:O(1)
 public int largestRectangleArea(int[] heights) {
    
    
        if (heights == null) return 0;
        int max = 0;
        for (int i = 0; i < heights.length; i++) {
    
    
            // min:这段矩形的最小高度
            // !!注意:每个格子是有宽度的,所以内层循环从i开始 --> 初始值:max=h[i],min=h[i]
            for (int j = i,min = 0; j < heights.length; j++) {
    
    
                min = Math.min(min, heights[j]);
                max = Math.max(max,(j - i + 1) * min);
            }
        }
        return max;
}

Solution 2: Monotonic Stack*

Monotonous stack + sentry. The role of the sentinel is to reduce the judgment of the empty stack and simplify the code logic

    public  int largestRectangleArea2(int[] heights){
    
    
        int  len = heights.length;
        if(len == 0)return 0;
        if(len == 1) return heights[0];
        int[] newHeights = new int[len+2];
        for (int i = 0; i <len ; i++) {
    
    
            newHeights[i+1] = heights[i];
        }
        len+=2;
        int area = 0;
        heights = newHeights;
        Deque<Integer> stack = new ArrayDeque<>();
        //加入哨兵元素,在循环中不用做非空判断
        stack.addLast(0);
        //数组下标入栈
        for (int i = 1; i <len ; i++) {
    
    
            //当前元素小于栈顶元素
            while(heights[i] < heights[stack.peekLast()]){
    
    
                int curHeight = heights[stack.pollLast()];
                int width = i - stack.peekLast()-1;
                area = Math.max(area,curHeight*width);
            }
            stack.addLast(i);
        }
        return area;
    }

Guess you like

Origin blog.csdn.net/weixin_43935927/article/details/108807082