Sword는 최소 함수를 포함하는 Offer30-stack (단조 스택)을 나타냅니다.

문제 설명

스택의 데이터 구조를 정의합니다.이 유형에서 스택의 가장 작은 요소를 가져올 수있는 min 함수를 구현하십시오.이 스택에서 min, push 및 pop을 호출하는 시간 복잡도는 O (1)입니다.

예:

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

문제 해결 아이디어 :

단조 적 스택의 문제는 기존의 사고에서 시작하여 문제의 본질을 파헤칠 수 있습니다
기존의 사고 : 일반 스택의 push () 및 pop () 함수의 복잡성은 O (1)입니다. 스택 min () 함수의 최소값 전체 스택을 통과해야하는 경우 복잡성은 O (N) 입니다.
이 질문의 어려움 : min () 함수의 복잡성을 O (1) O (1)로 줄입니다. 단조 스택을 구축하여 얻을 수 있습니다.
데이터 스택 A : 스택 A는 모든 요소를 ​​저장하는 데 사용되어 push ( ) 스택의 함수와 팝 pop () 함수는 스택의 top () 함수의 정상적인 논리를 얻습니다.
단조로운 스택 B : 스택 B는 엄격하지 않은 모든 요소를 ​​스택 A에 저장 한 다음 스택 A의 가장 작은 요소는 항상 스택 B의 맨 위 요소에 해당합니다. 즉, min () 함수는 다음의 맨 위 요소 만 반환하면됩니다. 스택 B .
따라서 엄격하지 않은 내림차순 (스택 맨 아래에서 스택 맨 위까지)을 유지하기 위해 스택 B의 요소 만 유지하면되고 min () 함수의 O (1) 복잡도는 다음과 같을 수 있습니다. 깨달았다.

push (x) :
먼저 요소를 스택 A로 푸시하고 , 스택 B가 비어 있으면 스택 B로 직접 푸시합니다. 그렇지 않으면 요소가 현재 스택 상단 요소보다 작거나 같을 때만 스택에 푸시됩니다. 비. 이러한 방식으로 스택 B가 스택의 맨 아래에서 맨 위까지 단조롭게 감소하는 것을 보장 할 수 있습니다 .

의심스러운 점 : 삽입 된 요소 만 스택 상단의 현재 요소보다 작을 때 스택 B로 푸시되는 이유 입니다.
스택 B의 최상위 요소가 최소값 min이고이 최소값 min은 요소 x가 삽입 될 때 스택 A에도 위치한다고 가정합니다.
x가 스택의 맨 위 요소보다 크면 스택 B에 삽입 할 필요가 없습니다. 이때 스택 A의 최소값은 여전히 ​​최소입니다. 스택은 후입 선출이므로 x는 min 전에 스택에서 튀어 나오고 삽입되지 않으면 더 작습니다.의 요소 이전에 스택에서 가장 작은 요소는 min이 터질 때까지 min으로 유지할 수 있습니다. 따라서
x가 스택의 맨 위 요소보다 작 으면 x를 스택 B에 삽입합니다. 이때 스택 A의 최소값은 x입니다. x가 팝되면 스택 B의 요소 x도 팝됩니다. min은 스택 A의 최소값이됩니다.
핵심은 스택 B의 "최소값"이 스택 A에서 이러한 "최소값"이 팝되는 순서와 동일한 순서로 팝된다는 것입니다.
pop () :
먼저 스택 A의 상위 요소를합니다. 요소가 스택 B의 상위 요소이면 스택 B의 상위 요소도 팝됩니다.
min ()
은 스택 B의 상위 요소로 직접 반환됩니다.
top ()
은 스택 A의 최상위 요소를 반환합니다.

구현 코드

class MinStack {
    
    
    public Stack<Integer> stack1;           //元素栈
    public Stack<Integer> stack2;           //单调栈
    /** initialize your data structure here. */
    public MinStack() {
    
    
        stack1=new Stack<Integer>();
        stack2=new Stack<Integer>();
    }
    
    public void push(int x) {
    
    
        stack1.push(x);     
        //只有栈2为空或者x比栈2的栈顶元素的值还要小(一定要包含等于)的时候,才会将x加入栈2中
        if(stack2.empty() || x<=stack2.peek()){
    
    
            stack2.push(x);
        }
    }
    
    public void pop() {
    
    
        int ele=stack1.pop();
        //当栈2不为空,且弹出的元素恰好等于栈2的栈顶元素值时,就把栈2的栈顶元素值也跟着弹出
        if(!stack2.empty() && ele==stack2.peek()){
    
    
           stack2.pop();
        }
    }
    
    public int top() {
    
    
        //直接返回栈1的栈顶元素值即可
        return stack1.peek();
    }
    
    public int min() {
    
    
        //直接返回栈2的栈顶元素值即可
        if(!stack2.empty()){
    
    
            return stack2.peek();
        }
        return 0;
    }
}

추천

출처blog.csdn.net/qq_39736597/article/details/113816319