设计一个特殊的栈,包含 min 函数。能够得到栈的最小元素。
要求函数 min、push 以及 pop 的时间复杂度都是 O(1)。
分析
由于时间复杂度的要求,我们不能用其他方法了,最简单的就是用空间换时间,给每个元素加一个min元素,表示压栈到现在最小的元素。
这样每次push时候,维护下data[top-1].min和当前val,取min值设到data[top].min即可。注意top=0时的特殊情况,min就是val。
特别提醒:企图整个栈共用一个min或者max辅助存储是错误的,因为一旦发生pop,min和max就会改变!
下面是代码,我还添加了一个max函数,也是复杂度O(1)的,原理一样,不解释了。
#include <stdio.h> #define MAX 100 struct Node { int data; int min; int max; }; struct Stack { struct Node data[MAX]; int top; }; void stack_init(struct Stack* stack) { stack->top = 0; } int stack_push(struct Stack* stack, int val) { if(stack->top>=MAX) { return -1; } stack->data[stack->top].data = val; if(stack->top==0) { stack->data[stack->top].min = stack->data[stack->top].max = val; }else { stack->data[stack->top].min = (val<stack->data[stack->top-1].min)?val:stack->data[stack->top-1].min; stack->data[stack->top].max = (val>stack->data[stack->top-1].max)?val:stack->data[stack->top-1].max; } stack->top++; return 0; } int stack_pop(struct Stack* stack, int* data) { if(stack->top==0) { return -1; } *data = stack->data[--stack->top].data; return 0; } int stack_top(struct Stack* stack, int* data) { if(stack->top==0) { return -1; } *data = stack->data[stack->top-1].data; return 0; } int stack_min(struct Stack* stack, int* data) { if(stack->top==0) { return -1; } *data = stack->data[stack->top-1].min; return 0; } int stack_max(struct Stack* stack, int* data) { if(stack->top==0) { return -1; } *data = stack->data[stack->top-1].max; return 0; } int main() { struct Stack stack; int i; int tmp; // Init stack_init(&stack); // Push 0 ~ 50 for(i=0;i<50;i++) { tmp = rand() % 100; printf("push %d\n", tmp); stack_push(&stack, tmp); } // Print top, min, max if(stack_top(&stack, &tmp)==0) { printf("top=%d\n", tmp); } if(stack_min(&stack, &tmp)==0) { printf("min=%d\n", tmp); } if(stack_max(&stack, &tmp)==0) { printf("max=%d\n", tmp); } // Pop 10 for(i=0;i<10;i++) { stack_pop(&stack, &tmp); } // Print top, min, max if(stack_top(&stack, &tmp)==0) { printf("top=%d\n", tmp); } if(stack_min(&stack, &tmp)==0) { printf("min=%d\n", tmp); } if(stack_max(&stack, &tmp)==0) { printf("max=%d\n", tmp); } return 0; }