包含min函数的栈
- 题目
- 数据范围:
- 示例
- C语言代码实现
- 解释
- 1. `push(value)`
- 2. `pop()`
- 3. `top()`
- 4. `min()`
- 总结
- 大小堆
题目
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的 min
函数,输入操作时保证 pop
、top
和 min
函数操作时,栈中一定有元素。
此栈包含的方法有:
push(value)
:将value
压入栈中pop()
:弹出栈顶元素top()
:获取栈顶元素min()
:获取栈中最小元素
数据范围:
- 操作数量满足 0 ≤ n ≤ 300 0 \leq n \leq 300 0≤n≤300
- 输入的元素满足 ∣ v a l ∣ ≤ 10000 |val| \leq 10000 ∣val∣≤10000
- 进阶:栈的各个操作的时间复杂度是 O ( 1 ) O(1) O(1),空间复杂度是 O ( n ) O(n) O(n)
示例
输入:
["PSH-1","PSH2","MIN","TOP","POP","PSH1","TOP","MIN"]
输出:
-1, 2, 1, -1
解析:
"PSH-1"
表示将-1压入栈中,栈中元素为-1
"PSH2"
表示将2压入栈中,栈中元素为2, -1
"MIN"
表示获取此时栈中最小元素==>返回-1
"TOP"
表示获取栈顶元素==>返回2
"POP"
表示弹出栈顶元素,弹出2,栈中元素为-1
"PSH1"
表示将1压入栈中,栈中元素为1, -1
"TOP"
表示获取栈顶元素==>返回1
"MIN"
表示获取此时栈中最小元素==>返回-1
C语言代码实现
#define MAX_SIZE 300 // 假设栈最大容量
int stack[MAX_SIZE]; // 定义一个整数数组作为栈的存储空间
int count = -1; // 用于记录栈中元素的数量// 压入栈中的值
void push(int value) {if (count < MAX_SIZE - 1) {stack[++count] = value;} else {printf("Stack is full.\n");return;}
}// 弹出栈顶元素
void pop() {if (count == -1) {printf("Stack is empty.\n");return;}count--;
}// 获取栈顶元素
int top() {if (count == -1) {return -1;}return stack[count]; // 返回栈顶元素的值
}// 获取栈中最小的元素
int min() {if (count == -1) {return -1;}int minVal = stack[0]; for (int i = 1; i <= count; i++) {minVal = (minVal > stack[i]) ? stack[i] : minVal;}return minVal;
}
解释
1. push(value)
该函数负责将一个元素压入栈中。当栈未满时,将元素存入 stack
数组,并将栈顶指针 count
增加。
2. pop()
该函数负责弹出栈顶元素。当栈不为空时,栈顶元素被移除,栈顶指针 count
减少。
3. top()
该函数返回栈顶的元素。如果栈为空,返回 -1
,否则返回栈顶的值。
4. min()
该函数遍历整个栈,找到最小的元素并返回。如果栈为空,返回 -1
。
总结
这题整体上还是很简单的,本以为是用大小堆实现的,没想到直接一个遍历就搞完了。明天研究一下如何用大小堆实现。
大小堆
#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 300 // 假设栈最大容量// 定义堆的结构体
typedef struct {int data[MAX_SIZE];int size; // 堆中的元素数量
} MinHeap;// 定义栈的结构体
typedef struct {int stack[MAX_SIZE];int top;MinHeap minHeap;
} Stack;// 堆的操作:插入元素
void insertMinHeap(MinHeap* heap, int value) {int i = heap->size++;heap->data[i] = value;// 维护堆的性质,逐步上浮while (i > 0 && heap->data[i] < heap->data[(i - 1) / 2]) {int temp = heap->data[i];heap->data[i] = heap->data[(i - 1) / 2];heap->data[(i - 1) / 2] = temp;i = (i - 1) / 2;}
}// 堆的操作:删除堆顶元素
void removeMinHeap(MinHeap* heap) {if (heap->size == 0) return;heap->data[0] = heap->data[--heap->size];// 维护堆的性质,逐步下沉int i = 0;while (2 * i + 1 < heap->size) {int left = 2 * i + 1;int right = 2 * i + 2;int smallest = i;if (left < heap->size && heap->data[left] < heap->data[smallest]) {smallest = left;}if (right < heap->size && heap->data[right] < heap->data[smallest]) {smallest = right;}if (smallest == i) break;int temp = heap->data[i];heap->data[i] = heap->data[smallest];heap->data[smallest] = temp;i = smallest;}
}// 堆的操作:获取堆顶元素
int getMin(MinHeap* heap) {return heap->size > 0 ? heap->data[0] : -1;
}// 初始化栈
void initStack(Stack* stack) {stack->top = -1;stack->minHeap.size = 0;
}// 压栈操作
void push(Stack* stack, int value) {if (stack->top < MAX_SIZE - 1) {stack->stack[++stack->top] = value;insertMinHeap(&stack->minHeap, value);} else {printf("Stack is full.\n");}
}// 弹栈操作
void pop(Stack* stack) {if (stack->top == -1) {printf("Stack is empty.\n");return;}int value = stack->stack[stack->top--];removeMinHeap(&stack->minHeap);
}// 获取栈顶元素
int top(Stack* stack) {if (stack->top == -1) {return -1;}return stack->stack[stack->top];
}// 获取栈中的最小元素
int min(Stack* stack) {return getMin(&stack->minHeap);
}int main() {Stack stack;initStack(&stack);push(&stack, -1);push(&stack, 2);printf("MIN: %d\n", min(&stack)); // 输出 -1printf("TOP: %d\n", top(&stack)); // 输出 2pop(&stack);printf("TOP: %d\n", top(&stack)); // 输出 -1printf("MIN: %d\n", min(&stack)); // 输出 -1return 0;
}