使用在 O(1) 时间和 O(1) 额外空间内支持 getMin() 的数组设计一个动态堆栈
使用支持所有堆栈操作的数组设计一个特殊的动态堆栈,例如push() 、 pop() 、 peek() 、 isEmpty()和getMin()操作,时间和空间复杂度恒定。
例子:
Assuming the right to left orientation as the top to bottom orientation and performing the operations:
- Push(10): 10 is added to the top of the stack. Thereafter, the stack modifies to {10}.
- Push(4): 4 is added to the top of the stack. Thereafter, the stack modifies to {10, 4}.
- Push(9): 9 is added to the top of the stack. Thereafter, the stack modifies to {10, 4, 9}.
- Push(6): 6 is added to the top of the stack. Thereafter, the stack modifies to {10, 4, 9, 6}.
- Push(5): 5 is added to the top of the stack. Thereafter, the stack modifies to {10, 4, 9, 6, 5}.
- Peek(): Prints the top element of the stack 5.
- getMin(): Prints the minimum element of the stack 4.
- Pop(): Deletes the top most element, 5 from the stack. Thereafter, the stack modifies to {10, 4, 9, 6}.
- Pop(): Deletes the top most element, 6 from the stack. Thereafter, the stack modifies to {10, 4, 9}.
- Pop(): Deletes the top most element, 9 from the stack. Thereafter, the stack modifies to {10, 4}.
- Pop(): Deletes the top most element, 4 from the stack. Thereafter, the stack modifies to {10}.
- Peek(): Prints the top element of the stack 10.
- getMin(): Prints the minimum element of the stack 10.
方法:要使用数组实现动态堆栈,想法是每次数组变满时将数组的大小加倍。请按照以下步骤解决问题:
- 初始化一个数组,比如arr[] ,初始大小为5 ,以实现堆栈。
- 此外,初始化两个变量,比如top和minEle来存储堆栈顶部元素和堆栈最小元素的索引。
- 现在,执行以下堆栈操作:
- isEmpty():检查堆栈是否为空。
- 如果顶部小于或等于0 ,则返回 true。否则,返回假。
- Push(x):在栈顶插入x 。
- 如果堆栈为空,则将x插入堆栈并使minEle等于x 。
- 如果堆栈不为空,则将x与minEle进行比较。出现两种情况:
- 如果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 ”。
- isEmpty():检查堆栈是否为空。
插图:
推(x)
- 要插入的数字: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。
流行音乐()
- 最初,堆栈中的最小元素 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)