📌  相关文章
📜  使用在 O(1) 时间和 O(1) 额外空间内支持 getMin() 的数组设计一个动态堆栈

📅  最后修改于: 2022-05-13 01:57:09.002000             🧑  作者: Mango

使用在 O(1) 时间和 O(1) 额外空间内支持 getMin() 的数组设计一个动态堆栈

使用支持所有堆栈操作的数组设计一个特殊的动态堆栈,例如push()pop()peek() 、 isEmpty()getMin()操作,时间和空间复杂度恒定。

例子:

方法:要使用数组实现动态堆栈,想法是每次数组变满时将数组的大小加倍。请按照以下步骤解决问题:

  • 初始化一个数组,比如arr[] ,初始大小为5 ,以实现堆栈。
  • 此外,初始化两个变量,比如topminEle来存储堆栈顶部元素和堆栈最小元素的索引。
  • 现在,执行以下堆栈操作:
    • isEmpty():检查堆栈是否为空。
      • 如果顶部小于或等于0 ,则返回 true。否则,返回假。
    • Push(x):在栈顶插入x
      • 如果堆栈为空,则将x插入堆栈并使minEle等于x
      • 如果堆栈不为空,则将xminEle进行比较。出现两种情况:
        • 如果x大于或等于minEle ,只需插入x
        • 如果x小于minEle ,则将(2*x – minEle)插入堆栈并使minEle等于x
      • 如果使用的数组已满,则将数组的大小加倍,然后将前一个数组的所有元素复制到新数组中,然后将新数组的地址分配给原始数组。此后,执行上述推送操作。
    • Pop():从栈顶移除一个元素。
      • 让移除的元素为y 。出现两种情况
      • 如果y大于或等于minEle ,则堆栈中的最小元素仍然是minEle
      • 如果y小于minEle ,则最小元素现在变为(2*minEle – y) ,因此将minEle更新为minEle = 2*minEle-y
    • getMin():查找堆栈的最小值。
      • 如果堆栈不为空,则返回minEle的值。否则,返回“ -1 ”并打印“ Underflow ”。

插图:

推(x)

stack_insert

  • 要插入的数字:3,堆栈为空,因此将 3 插入堆栈,minEle = 3。
  • 要插入的数字:5,堆栈不为空,5> minEle,将 5 插入堆栈,minEle = 3。
  • 要插入的数字:2,堆栈不为空,2< minEle,将(2*2-3 = 1)插入堆栈,minEle = 2。
  • 要插入的数字:1,堆栈不为空,1< minEle,将(2*1-2 = 0)插入堆栈,minEle = 1。
  • 要插入的数字:1,堆栈不为空,1 = minEle,将 1 插入堆栈,minEle = 1。
  • 要插入的数字:-1,堆栈不为空,-1 < minEle,将 (2*-1 – 1 = -3) 插入堆栈并且 minEle = -1。

流行音乐()

stack_removal

  • 最初,堆栈中的最小元素 minEle 为 -1。
  • 删除的数字:-3,由于 -3 小于最小元素,因此要删除的原始数字是 minEle,即 -1,新的 minEle = 2*-1 – (-3) = 1
  • 移除的数字:1, 1 == minEle,所以移除的数字是 1,minEle 仍然等于 1。
  • 删除的数字:0, 0< minEle,原始数字是 minEle,即 1,新的 minEle = 2*1 – 0 = 2。
  • 删除的数字:1, 1< minEle,原始数字是 minEle,即 2,新的 minEle = 2*2 – 1 = 3。
  • 去掉的数字:5, 5> minEle,原来的数字是5,minEle还是3

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// A class to create
// our special stack
class Stack {
private:
   
    // Initial size of
    // the Array
    int Max = 5;
 
    // Array for the stack
    // implementation
    int* arr = new int(Max);
 
    // Stores the minimum
    // Element of the stack
    int minEle = 0;
 
    // Stores the top element
    // of the stack
    int top = 0;
 
public:
    // Method to check whether
    // stack is empty or not
    bool empty()
    {
        if (top <= 0) {
            return true;
        }
        else {
            return false;
        }
    }
    // Method to push elements
    // to the Special Stack
    void push(int x)
    {
        // If stack is empty
        if (empty()) {
 
            // Assign x to minEle
            minEle = x;
 
            // Assign x to arr[top]
            arr[top] = x;
 
            // Increment top by 1
            top++;
        }
        // If array is full
        else if (top == Max) {
 
            // Update the Max size
            Max = 2 * Max;
 
            int* temp = new int(Max);
 
            // Traverse the array arr[]
            for (int i = 0; i < top; i++) {
                temp[i] = arr[i];
            }
 
            // If x is less than minEle
            if (x < minEle) {
 
                // Push 2*x-minEle
                temp[top] = 2 * x - minEle;
 
                // Assign x to minEle
                minEle = x;
 
                top++;
            }
            // Else
            else {
 
                // Push x to stack
                temp[top] = x;
                top++;
            }
            // Assign address of the
            // temp to arr
            arr = temp;
        }
        else {
            // If x is less
            // than minEle
            if (x < minEle) {
 
                // Push 2*x-minEle
                arr[top] = 2 * x - minEle;
                top++;
 
                // Update minEle
                minEle = x;
            }
            else {
                // Push x to the
                // stack
                arr[top] = x;
                top++;
            }
        }
    }
    // Method to pop the elements
    // from the stack.
    void pop()
    {
        // If stack is empty
        if (empty()) {
            cout << "Underflow" << endl;
            return;
        }
        // Stores the top element
        // of the stack
        int t = arr[top - 1];
 
        // If t is less than
        // the minEle
        if (t < minEle) {
            // Pop the minEle
            cout << "Popped element : " << minEle << endl;
 
            // Update minEle
            minEle = 2 * minEle - t;
        }
        // Else
        else {
            // Pop the topmost element
            cout << "Popped element : " << t << endl;
        }
        top--;
        return;
    }
 
    // Method to find the topmost
    // element of the stack
    int peek()
    {
        // If stack is empty
        if (empty()) {
            cout << "Underflow" << endl;
            return -1;
        }
 
        // Stores the top element
        // of the stack
        int t = arr[top - 1];
 
        // If t is less than
        // the minEle
        if (t < minEle) {
            return minEle;
        }
        // Else
        else {
            return t;
        }
    }
    // Method to find the Minimum
    // element of the Special stack
    int getMin()
    {
        // If stack is empty
        if (empty()) {
            cout << "Underflow" << endl;
            return -1;
        }
        // Else
        else {
            return minEle;
        }
    }
};
// Driver Code
int main()
{
    Stack S;
 
    S.push(10);
    S.push(4);
    S.push(9);
    S.push(6);
    S.push(5);
 
    cout << "Top Element : " << S.peek() << endl;
 
    cout << "Minimum Element : " << S.getMin() << endl;
 
    S.pop();
    S.pop();
    S.pop();
    S.pop();
 
    cout << "Top Element : " << S.peek() << endl;
    cout << "Minimum Element : " << S.getMin() << endl;
 
    return 0;
}


Java
// Java program for the above approach
public class Main
{
    // Initial size of
    // the Array
    static int Max = 5;
     
    // Array for the stack
    // implementation
    static int[] arr = new int[Max];
     
    // Stores the minimum
    // Element of the stack
    static int minEle = 0;
     
    // Stores the top element
    // of the stack
    static int Top = 0;
       
    // Method to check whether
    // stack is empty or not
    static boolean empty()
    {
        if (Top <= 0) {
            return true;
        }
        else {
            return false;
        }
    }
    // Method to push elements
    // to the Special Stack
    static void push(int x)
    {
        // If stack is empty
        if (empty()) {
     
            // Assign x to minEle
            minEle = x;
     
            // Assign x to arr[top]
            arr[Top] = x;
     
            // Increment top by 1
            Top++;
        }
        // If array is full
        else if (Top == Max) {
     
            // Update the Max size
            Max = 2 * Max;
     
            int[] temp = new int[Max];
     
            // Traverse the array arr[]
            for (int i = 0; i < Top; i++) {
                temp[i] = arr[i];
            }
     
            // If x is less than minEle
            if (x < minEle) {
     
                // Push 2*x-minEle
                temp[Top] = 2 * x - minEle;
     
                // Assign x to minEle
                minEle = x;
     
                Top++;
            }
            // Else
            else {
     
                // Push x to stack
                temp[Top] = x;
                Top++;
            }
            // Assign address of the
            // temp to arr
            arr = temp;
        }
        else {
            // If x is less
            // than minEle
            if (x < minEle) {
     
                // Push 2*x-minEle
                arr[Top] = 2 * x - minEle;
                Top++;
     
                // Update minEle
                minEle = x;
            }
            else {
                // Push x to the
                // stack
                arr[Top] = x;
                Top++;
            }
        }
    }
    // Method to pop the elements
    // from the stack.
    static void pop()
    {
        // If stack is empty
        if (empty()) {
            System.out.print("Underflow");
            return;
        }
        // Stores the top element
        // of the stack
        int t = arr[Top - 1];
     
        // If t is less than
        // the minEle
        if (t < minEle) {
            // Pop the minEle
            System.out.println("Popped element : " + minEle);
     
            // Update minEle
            minEle = 2 * minEle - t;
        }
        // Else
        else {
            // Pop the topmost element
            System.out.println("Popped element : " + t);
        }
        Top--;
        return;
    }
     
    // Method to find the topmost
    // element of the stack
    static int peek()
    {
        // If stack is empty
        if (empty()) {
            System.out.println("Underflow");
            return -1;
        }
     
        // Stores the top element
        // of the stack
        int t = arr[Top - 1];
     
        // If t is less than
        // the minEle
        if (t < minEle) {
            return minEle;
        }
        // Else
        else {
            return t;
        }
    }
    // Method to find the Minimum
    // element of the Special stack
    static int getMin()
    {
        // If stack is empty
        if (empty()) {
            System.out.println("Underflow");
            return -1;
        }
        // Else
        else {
            return minEle;
        }
    }
     
  // Driver code
    public static void main(String[] args) {
        push(10);
        push(4);
        push(9);
        push(6);
        push(5);
         
        System.out.println("Top Element : " + peek());
         
        System.out.println("Minimum Element : " + getMin());
         
        pop();
        pop();
        pop();
        pop();
         
        System.out.println("Top Element : " + peek());
        System.out.println("Minimum Element : " + getMin());
    }
}
 
// This code is contributed by rameshtravel07.


Python3
# Python3 program for the above approach
     
# Initial size of
# the Array
Max = 5
 
# Array for the stack
# implementation
arr = [0]*Max
 
# Stores the minimum
# Element of the stack
minEle = 0
 
# Stores the top element
# of the stack
Top = 0
 
# Method to check whether
# stack is empty or not
def empty():
 
    if (Top <= 0):
        return True
    else:
        return False
 
# Method to push elements
# to the Special Stack
def push(x):
    global arr, Top, Max, minEle
     
    # If stack is empty
    if empty():
       
        # Assign x to minEle
        minEle = x
 
        # Assign x to arr[top]
        arr[Top] = x
 
        # Increment top by 1
        Top+=1
    # If array is full
    elif (Top == Max):
 
        # Update the Max size
        Max = 2 * Max
 
        temp = [0]*Max
 
        # Traverse the array arr[]
        for i in range(Top):
            temp[i] = arr[i]
 
        # If x is less than minEle
        if (x < minEle):
            # Push 2*x-minEle
            temp[Top] = 2 * x - minEle
 
            # Assign x to minEle
            minEle = x
 
            Top+=1
        # Else
        else:
            # Push x to stack
            temp[Top] = x
            Top+=1
        # Assign address of the
        # temp to arr
        arr = temp
    else:
        # If x is less
        # than minEle
        if (x < minEle):
            # Push 2*x-minEle
            arr[Top] = 2 * x - minEle
            Top+=1
 
            # Update minEle
            minEle = x
        else:
            # Push x to the
            # stack
            arr[Top] = x
            Top+=1
 
# Method to pop the elements
# from the stack.
def pop():
    global Top, minEle
 
    # If stack is empty
    if empty():
        print("Underflow")
        return
     
    # Stores the top element
    # of the stack
    t = arr[Top - 1]
 
    # If t is less than
    # the minEle
    if (t < minEle) :
        # Pop the minEle
        print("Popped element :", minEle)
 
        # Update minEle
        minEle = 2 * minEle - t
    # Else
    else:
        # Pop the topmost element
        print("Popped element :", t)
    Top-=1
    return
 
# Method to find the topmost
# element of the stack
def peek():
    # If stack is empty
    if empty():
        print("Underflow")
        return -1
 
    # Stores the top element
    # of the stack
    t = arr[Top - 1]
 
    # If t is less than
    # the minEle
    if (t < minEle):
        return minEle
    # Else
    else:
        return t
 
# Method to find the Minimum
# element of the Special stack
def getMin():
    # If stack is empty
    if empty():
        print("Underflow")
        return -1
       
    # Else
    else:
        return minEle
 
push(10)
push(4)
push(9)
push(6)
push(5)
 
print("Top Element :", peek())
 
print("Minimum Element :", getMin())
 
pop()
pop()
pop()
pop()
 
print("Top Element :", peek())
print("Minimum Element :", getMin())
 
# This code is contributed by mukesh07.


C#
// C# program for the above approach
using System;
class GFG {
     
    // Initial size of
    // the Array
    static int Max = 5;
    
    // Array for the stack
    // implementation
    static int[] arr = new int[Max];
    
    // Stores the minimum
    // Element of the stack
    static int minEle = 0;
    
    // Stores the top element
    // of the stack
    static int Top = 0;
      
    // Method to check whether
    // stack is empty or not
    static bool empty()
    {
        if (Top <= 0) {
            return true;
        }
        else {
            return false;
        }
    }
    // Method to push elements
    // to the Special Stack
    static void push(int x)
    {
        // If stack is empty
        if (empty()) {
    
            // Assign x to minEle
            minEle = x;
    
            // Assign x to arr[top]
            arr[Top] = x;
    
            // Increment top by 1
            Top++;
        }
        // If array is full
        else if (Top == Max) {
    
            // Update the Max size
            Max = 2 * Max;
    
            int[] temp = new int[Max];
    
            // Traverse the array arr[]
            for (int i = 0; i < Top; i++) {
                temp[i] = arr[i];
            }
    
            // If x is less than minEle
            if (x < minEle) {
    
                // Push 2*x-minEle
                temp[Top] = 2 * x - minEle;
    
                // Assign x to minEle
                minEle = x;
    
                Top++;
            }
            // Else
            else {
    
                // Push x to stack
                temp[Top] = x;
                Top++;
            }
            // Assign address of the
            // temp to arr
            arr = temp;
        }
        else {
            // If x is less
            // than minEle
            if (x < minEle) {
    
                // Push 2*x-minEle
                arr[Top] = 2 * x - minEle;
                Top++;
    
                // Update minEle
                minEle = x;
            }
            else {
                // Push x to the
                // stack
                arr[Top] = x;
                Top++;
            }
        }
    }
    // Method to pop the elements
    // from the stack.
    static void pop()
    {
        // If stack is empty
        if (empty()) {
            Console.WriteLine("Underflow");
            return;
        }
        // Stores the top element
        // of the stack
        int t = arr[Top - 1];
    
        // If t is less than
        // the minEle
        if (t < minEle) {
            // Pop the minEle
            Console.WriteLine("Popped element : " + minEle);
    
            // Update minEle
            minEle = 2 * minEle - t;
        }
        // Else
        else {
            // Pop the topmost element
            Console.WriteLine("Popped element : " + t);
        }
        Top--;
        return;
    }
    
    // Method to find the topmost
    // element of the stack
    static int peek()
    {
        // If stack is empty
        if (empty()) {
            Console.WriteLine("Underflow");
            return -1;
        }
    
        // Stores the top element
        // of the stack
        int t = arr[Top - 1];
    
        // If t is less than
        // the minEle
        if (t < minEle) {
            return minEle;
        }
        // Else
        else {
            return t;
        }
    }
    // Method to find the Minimum
    // element of the Special stack
    static int getMin()
    {
        // If stack is empty
        if (empty()) {
            Console.WriteLine("Underflow");
            return -1;
        }
        // Else
        else {
            return minEle;
        }
    }
     
  static void Main() {
    push(10);
    push(4);
    push(9);
    push(6);
    push(5);
    
    Console.WriteLine("Top Element : " + peek());
    
    Console.WriteLine("Minimum Element : " + getMin());
    
    pop();
    pop();
    pop();
    pop();
    
    Console.WriteLine("Top Element : " + peek());
    Console.WriteLine("Minimum Element : " + getMin());
  }
}
 
// This code is contributed by suresh07.


Javascript



输出
Top Element : 5
Minimum Element : 4
Popped element : 5
Popped element : 6
Popped element : 9
Popped element : 4
Top Element : 10
Minimum Element : 10

时间复杂度:每个操作 O(1)
辅助空间: O(1)