📌  相关文章
📜  在O(1)时间和O(1)额外空间中查找堆栈中的最大值

📅  最后修改于: 2021-04-17 09:57:59             🧑  作者: Mango

给定一堆整数。我们的任务是设计一个特殊的堆栈,以便可以在O(1)时间和O(1)额外空间中找到最大元素。

例子

Given Stack :
2
5
1
64   --> Maximum

So Output must be 64 when getMax() is called.

下面是设计用来从堆栈中压入和弹出元素的不同功能。
Push(x) :在堆栈顶部插入x。

  • 如果堆栈为空,则将x插入堆栈,并使maxEle等于x。
  • 如果堆栈不为空,则将x与maxEle进行比较。出现两种情况:
    • 如果x小于或等于maxEle,只需插入x。
    • 如果x大于maxEle,则将(2 * x – maxEle)插入堆栈,并使maxEle等于x。例如,让先前的maxEle为3。现在我们要插入4。我们将maxEle更新为4,然后将2 * 4 – 3 = 5插入堆栈。

Pop():从堆栈顶部删除一个元素。

  • 从顶部删除元素。令移除的元素为y。出现两种情况:
    • 如果y小于或等于maxEle,则堆栈中的最大元素仍为maxEle。
    • 如果y大于maxEle,则最大元素现在变为(2 * maxEle – y),因此进行更新(maxEle = 2 * maxEle – y)。在这里,我们从当前最大值及其堆栈中的值中检索先前的最大值。例如,让要删除的元素为5,maxEle为4。我们删除5并将maxEle更新为2 * 4 – 5 = 3。

重要事项:

  • 如果到目前为止,堆栈不保存元素的实际值。
  • 实际的最大元素始终存储在maxEle中

插图

推(x)

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

流行音乐()

  • 最初,堆栈中的最大元素maxEle为5。
  • 删除的数字:1,因为1小于maxEle,所以仅弹出1。maxEle = 5。
  • 删除的数字:2、2
  • 删除的数字:7、7> maxEle,原始数字为maxEle,即5,新的maxEle = 2 * 5 – 7 = 3。
C++
// C++ program to implement a stack that supports
// getMaximum() in O(1) time and O(1) extra space.
#include 
using namespace std;
  
// A user defined stack that supports getMax() in
// addition to push() and pop()
struct MyStack {
    stack s;
    int maxEle;
  
    // Prints maximum element of MyStack
    void getMax()
    {
        if (s.empty())
            cout << "Stack is empty\n";
  
        // variable maxEle stores the maximum element
        // in the stack.
        else
            cout << "Maximum Element in the stack is: "
                 << maxEle << "\n";
    }
  
    // Prints top element of MyStack
    void peek()
    {
        if (s.empty()) {
            cout << "Stack is empty ";
            return;
        }
  
        int t = s.top(); // Top element.
  
        cout << "Top Most Element is: ";
  
        // If t < maxEle means maxEle stores
        // value of t.
        (t > maxEle) ? cout << maxEle : cout << t;
    }
  
    // Remove the top element from MyStack
    void pop()
    {
        if (s.empty()) {
            cout << "Stack is empty\n";
            return;
        }
  
        cout << "Top Most Element Removed: ";
        int t = s.top();
        s.pop();
  
        // Maximum will change as the maximum element
        // of the stack is being removed.
        if (t > maxEle) {
            cout << maxEle << "\n";
            maxEle = 2 * maxEle - t;
        }
  
        else
            cout << t << "\n";
    }
  
    // Removes top element from MyStack
    void push(int x)
    {
        // Insert new number into the stack
        if (s.empty()) {
            maxEle = x;
            s.push(x);
            cout << "Number Inserted: " << x << "\n";
            return;
        }
  
        // If new number is less than maxEle
        if (x > maxEle) {
            s.push(2 * x - maxEle);
            maxEle = x;
        }
  
        else
            s.push(x);
  
        cout << "Number Inserted: " << x << "\n";
    }
};
  
// Driver Code
int main()
{
    MyStack s;
    s.push(3);
    s.push(5);
    s.getMax();
    s.push(7);
    s.push(19);
    s.getMax();
    s.pop();
    s.getMax();
    s.pop();
    s.peek();
  
    return 0;
}


Java
// Java program to implement a stack that supports
// getMaximum() in O(1) time and O(1) extra space.
import java.util.*;
  
class GFG 
{
  
// A user defined stack that supports getMax() in
// addition to push() and pop()
static class MyStack 
{
    Stack s = new Stack();
    int maxEle;
  
    // Prints maximum element of MyStack
    void getMax()
    {
        if (s.empty())
            System.out.print("Stack is empty\n");
  
        // variable maxEle stores the maximum element
        // in the stack.
        else
            System.out.print("Maximum Element in" + 
                        "the stack is: "+maxEle + "\n");
  
    }
  
    // Prints top element of MyStack
    void peek()
    {
        if (s.empty())
        {
              
            System.out.print("Stack is empty ");
            return;
        }
  
        int t = s.peek(); // Top element.
  
        System.out.print("Top Most Element is: ");
  
        // If t < maxEle means maxEle stores
        // value of t.
        if(t > maxEle)
            System.out.print(maxEle);
        else
            System.out.print(t);
    }
  
    // Remove the top element from MyStack
    void pop()
    {
        if (s.empty()) 
        {
            System.out.print("Stack is empty\n");
            return;
        }
  
        System.out.print("Top Most Element Removed: ");
        int t = s.peek();
        s.pop();
  
        // Maximum will change as the maximum element
        // of the stack is being removed.
        if (t > maxEle)
        {
            System.out.print(maxEle + "\n");
            maxEle = 2 * maxEle - t;
        }
  
        else
            System.out.print(t + "\n");
    }
  
    // Removes top element from MyStack
    void push(int x)
    {
        // Insert new number into the stack
        if (s.empty()) 
        {
            maxEle = x;
            s.push(x);
            System.out.print("Number Inserted: " + x + "\n");
            return;
        }
  
        // If new number is less than maxEle
        if (x > maxEle) 
        {
            s.push(2 * x - maxEle);
            maxEle = x;
        }
  
        else
            s.push(x);
  
        System.out.print("Number Inserted: " + x + "\n");
    }
};
  
// Driver Code
public static void main(String[] args) 
{
    MyStack s = new MyStack();
    s.push(3);
    s.push(5);
    s.getMax();
    s.push(7);
    s.push(19);
    s.getMax();
    s.pop();
    s.getMax();
    s.pop();
    s.peek();
    }
}
  
/* This code contributed by PrinciRaj1992 */


Python 3
# Class to make a Node 
class Node:
    #Constructor which assign argument to nade's value 
    def __init__(self, value):
        self.value = value
        self.next = None
    
    # This method returns the string representation of the object.
    def __str__(self):
        return "Node({})".format(self.value)
      
    #  __repr__ is same as __str__
    __repr__ = __str__
    
  
class Stack:
    # Stack Constructor initialise top of stack and counter.
    def __init__(self):
        self.top = None
        self.count = 0
        self.maximum = None
          
    #This method returns the string representation of the object (stack).
    def __str__(self):
        temp=self.top
        out=[]
        while temp:
            out.append(str(temp.value))
            temp=temp.next
        out='\n'.join(out)
        return ('Top {} \n\nStack :\n{}'.format(self.top,out))
          
    #  __repr__ is same as __str__
    __repr__=__str__
      
    #This method is used to get minimum element of stack
    def getMax(self):
        if self.top is None:
            return "Stack is empty"
        else:
            print("Maximum Element in the stack is: {}" .format(self.maximum))
  
   
  
    # Method to check if Stack is Empty or not
    def isEmpty(self):
        # If top equals to None then stack is empty 
        if self.top == None:
            return True
        else:
        # If top not equal to None then stack is empty 
            return False
  
    # This method returns length of stack       
    def __len__(self):
        self.count = 0
        tempNode = self.top
        while tempNode:
            tempNode = tempNode.next
            self.count+=1
        return self.count
  
    # This method returns top of stack       
    def peek(self):
        if self.top is None:
            print ("Stack is empty")
        else:    
            if self.top.value > self.maximum:
                print("Top Most Element is: {}" .format(self.maximum))
            else:
                print("Top Most Element is: {}" .format(self.top.value))
  
    #This method is used to add node to stack
    def push(self,value):
        if self.top is None:
            self.top = Node(value)
            self.maximum = value
              
        elif value > self.maximum :
            temp = (2 * value) - self.maximum
            new_node = Node(temp)
            new_node.next = self.top
            self.top = new_node
            self.maximum = value
        else:
            new_node = Node(value)
            new_node.next = self.top
            self.top = new_node
        print("Number Inserted: {}" .format(value))
    
    #This method is used to pop top of stack
    def pop(self):
        if self.top is None:
            print( "Stack is empty")
        else:
            removedNode = self.top.value
            self.top = self.top.next
            if removedNode > self.maximum:
                print ("Top Most Element Removed :{} " .format(self.maximum))
                self.maximum = ( ( 2 * self.maximum ) - removedNode )
            else:
                print ("Top Most Element Removed : {}" .format(removedNode))
  
                  
              
      
 # Driver program to test above class  
stack = Stack() 
  
stack.push(3)
stack.push(5) 
stack.getMax()
stack.push(7)
stack.push(19)
stack.getMax()     
stack.pop()
stack.getMax()
stack.pop() 
stack.peek()
  
# This code is contributed by Blinkii


C#
// C# program to implement a stack that supports 
// getMaximum() in O(1) time and O(1) extra space. 
using System; 
using System.Collections.Generic;
  
class GFG 
{ 
  
// A user defined stack that supports getMax() in 
// addition to push() and pop() 
public class MyStack 
{ 
    public Stack s = new Stack(); 
    public int maxEle; 
  
    // Prints maximum element of MyStack 
    public void getMax() 
    { 
        if (s.Count == 0) 
            Console.Write("Stack is empty\n"); 
  
        // variable maxEle stores the maximum element 
        // in the stack. 
        else
            Console.Write("Maximum Element in" + 
                        "the stack is: "+maxEle + "\n"); 
  
    } 
  
    // Prints top element of MyStack 
    public void peek() 
    { 
        if (s.Count == 0) 
        { 
              
            Console.Write("Stack is empty "); 
            return; 
        } 
  
        int t = s.Peek(); // Top element. 
  
        Console.Write("Top Most Element is: "); 
  
        // If t < maxEle means maxEle stores 
        // value of t. 
        if(t > maxEle) 
            Console.Write(maxEle); 
        else
            Console.Write(t); 
    } 
  
    // Remove the top element from MyStack 
    public void pop() 
    { 
        if (s.Count == 0) 
        { 
            Console.Write("Stack is empty\n"); 
            return; 
        } 
  
        Console.Write("Top Most Element Removed: "); 
        int t = s.Peek(); 
        s.Pop(); 
  
        // Maximum will change as the maximum element 
        // of the stack is being removed. 
        if (t > maxEle) 
        { 
            Console.Write(maxEle + "\n"); 
            maxEle = 2 * maxEle - t; 
        } 
  
        else
            Console.Write(t + "\n"); 
    } 
  
    // Removes top element from MyStack 
    public void push(int x) 
    { 
        // Insert new number into the stack 
        if (s.Count == 0) 
        { 
            maxEle = x; 
            s.Push(x); 
            Console.Write("Number Inserted: " + x + "\n"); 
            return; 
        } 
  
        // If new number is less than maxEle 
        if (x > maxEle) 
        { 
            s.Push(2 * x - maxEle); 
            maxEle = x; 
        } 
  
        else
            s.Push(x); 
  
        Console.Write("Number Inserted: " + x + "\n"); 
    } 
}; 
  
// Driver Code 
public static void Main(String[] args) 
{ 
    MyStack s = new MyStack(); 
    s.push(3); 
    s.push(5); 
    s.getMax(); 
    s.push(7); 
    s.push(19); 
    s.getMax(); 
    s.pop(); 
    s.getMax(); 
    s.pop(); 
    s.peek(); 
} 
} 
  
// This code is contributed by Princi Singh


输出:
Number Inserted: 3
Number Inserted: 5
Maximum Element in the stack is: 5
Number Inserted: 7
Number Inserted: 19
Maximum Element in the stack is: 19
Top Most Element Removed: 19
Maximum Element in the stack is: 7
Top Most Element Removed: 7
Top Most Element is: 5