剑指Offer-数据结构 30. 包含 min 函数的栈

剑指Offer-数据结构 30. 包含 min 函数的栈

Q:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)

示例:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.min();   --> 返回 -2.
 

提示:

各函数的调用总次数不超过 20000 次

 


这个题目如果只是单纯的实现一个栈的pop,top,min都比较简单,但是这里要求时间复杂度是O(1)

我们普通的实现就需要遍历一遍查找最小的元素,时间复杂度必然就到了O(N).​​​​​​​这里可以采用和之前用2个栈实现队列的方法来实现,用一个栈有序存入数据,则取得时候直接取该栈顶元素就是最小的,push元素到A栈的时候和A栈中的元素对比,如果小于A中的元素就同时push到B栈中,top直接取A栈顶元素,pop的时候需要判断同时移除A和B中的该元素。

typedef int STACK_TYPE;

/***************************************************
 *              Stack Operation
 ***************************************************/
typedef struct STACK_NODE {
    STACK_TYPE value;
    struct STACK_NODE *next;
}StackNode;

//destory stack
void destory(StackNode **stack) {
    while(!is_empty(*stack)) {
        pop(stack);
    }
}

//push
void push(StackNode **stack, STACK_TYPE value) {
    StackNode *new_node = (StackNode *)malloc(sizeof(StackNode));
    assert(new_node != NULL);

    //insert the new node into head
    new_node->next = *stack;
    new_node->value = value;
    *stack = new_node;
}

//pop
void pop(StackNode **stack) {
    StackNode *head;
    assert(!is_empty(*stack));

    head = *stack;
    *stack = head->next;
    free(head);
}

//top
STACK_TYPE top(const StackNode *const stack) {
    assert(!is_empty(stack));
    return stack->value;
}

//is_empty
int is_empty(const StackNode * const stack) {
    return stack == NULL;
}

//never full
int is_full(const StackNode * const stack) {
    return FALSE;
}

void demo_push(StackNode **stack_a, StackNode **stack_b,STACK_TYPE value) {
    push(stack_a, value);
    //栈B是栈A的非严格降序
    if(is_empty(*stack_b) || value <= top(*stack_b)) {
        push(stack_b, value);
    }
}

void demo_pop(StackNode **stack_a, StackNode **stack_b) {
    if(top(*stack_a) == top(*stack_b)) {
        pop(stack_b);
    }
    pop(stack_a);
}

STACK_TYPE demo_top(const StackNode * const stack) {
    return top(stack);
}

STACK_TYPE demo_min_top(const StackNode * const stack) {
    return top(stack);
}

void display_stack(const StackNode * const stack) {
    StackNode *p = stack;
    while(p != NULL) {
        printf(" %d ", p->value);
        p = p->next;
    }
}

/***************************************************
 *              Main
 ***************************************************/
int main() {

    static StackNode *stack_a;
    static StackNode *stack_b;

    printf("push : 6\n");
    demo_push(&stack_a, &stack_b, 6);

    printf("push : 8\n");
    demo_push(&stack_a, &stack_b, 8);

    printf("push : 2\n");
    demo_push(&stack_a, &stack_b, 2);

    printf("push : 4\n");
    demo_push(&stack_a, &stack_b, 4);

    printf("stack_a: ");
    display_stack(stack_a);
    printf("\n");

    printf("stack_b: ");
    display_stack(stack_b);
    printf("\n");


    printf("top: %d\n", demo_top(stack_a));
    printf("min_top: %d\n", demo_min_top(stack_b));

    printf("pop...\n");
    demo_pop(&stack_a, &stack_b);

    printf("top: %d\n", demo_top(stack_a));
    printf("min_top: %d\n", demo_min_top(stack_b));

    printf("stack_a: ");
    display_stack(stack_a);
    printf("\n");

    printf("stack_b: ");
    display_stack(stack_b);
    printf("\n");

    destory(&stack_a);
    destory(&stack_b);
    return 0;
}

小结:

这个题目主要考察对栈的实现和对算法效率时间复杂度的理解,如何保证高效的栈操作,这个用双栈实现一些对栈顺序有所要求的操作技巧需要掌握,可能面试中会遇到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值