包含min函数的栈

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

设计思路:     我们要做的是在我们每次数据入栈的时候,记录当前数据栈中最小值,并且在pop()出栈之后依然能找到最小值;

    方案①,如果只用一个 min 变量来保存每次入栈时候的最小值,那么出栈的时候,当前的最小值还是栈中的最小值吗?假设栈中的数据按入栈顺序依次为[ 2, 3, 5, 1 ] ,很明显此时记录的min值为1,那么当我们pop()出一条数据之后,堆栈变为 [ 2, 3, 5 ] ,此时的最小值应为2,但是记录的min值为1,最小值记录已丢失,此方案不通。

    方案②,基于方案①的问题,我们应该设计一个结构,能够保存我们每一步入栈的时候情况下的当前最小值。可能我们会想到用数组结构排序后取最小值,但是要保证时间复杂度为O(1),那么数组结构方案舍弃(没有一种数组排序为O(1)复杂度)。

    方案③,在这里我采用堆栈结构来保存记录最小值,为什么采用堆栈呢,堆栈结构有一个特点是保护现场和恢复现场的功能。想象一下,每次我们数据入栈时保存最小值,出栈的时候还要能恢复上一次的最小值,是不是和堆栈的这个特点不谋而合呢。所以我们采用堆栈结构。当然,在这里我们需要使用双倍的存储空间来实现功能,以空间换取时间╮(╯▽╰)╭。

首先我们实现一个Stack结构,代码如下:

 1 class Stack {
 2     constructor() {
 3         this.stack = []
 4     }
 5     push(v) {
 6         this.stack.push(v)
 7     }
 8     pop() {
 9         this.stack.pop()
10     }
11     isEmpty() {
12         return !this.count()
13     }
14     count() {
15         return this.stack.length
16     }
17     top() {
18         return this.stack[this.count() - 1]
19     }
20 }

接着实现最小堆栈代码

 1 class MinStack {
 2     data_stack = new Stack() // 存放真正的栈数据
 3     min_stack = new Stack() // 存放最小值栈
 4     constructor() { }
 5     push(val) {
 6         const min_stack = this.min_stack;
 7         // 数据入栈
 8         this.data_stack.push(val);
 9         /* 在最小堆栈中记录每一次更新堆栈的当前情况下的最小值,
10         即保证最小栈栈顶始终记录的是当前数据栈中最小的那个值,
11         那么在每次pop的时候,最小栈栈顶记录的依旧记录的是最小值,
12         就不用担心第二小值的问题啦 */
13         if (min_stack.isEmpty() || val < min_stack.top()) {
14             min_stack.push(val)
15         } else {
16             min_stack.push(min_stack.top())
17         }
18     }
19     pop() {
20         this.data_stack.pop()
21         this.min_stack.pop()
22     }
23     min() {
24         return this.min_stack.top()
25     }
26 }

测试结果

完整代码如下

class Stack {
    constructor() {
        this.stack = []
    }
    push(v) {
        this.stack.push(v)
    }
    pop() {
        this.stack.pop()
    }
    isEmpty() {
        return !this.count()
    }
    count() {
        return this.stack.length
    }
    top() {
        return this.stack[this.count() - 1]
    }
}

class MinStack {
    data_stack = new Stack() // 存放真正的栈数据
    min_stack = new Stack() // 存放最小值栈
    constructor() { }
    push(val) {
        const min_stack = this.min_stack;
        // 数据入栈
        this.data_stack.push(val);
        /* 在最小堆栈中记录每一次更新堆栈的当前情况下的最小值,
        即保证最小栈栈顶始终记录的是当前数据栈中最小的那个值,
        那么在每次pop的时候,最小栈栈顶记录的依旧记录的是最小值,
        就不用担心第二小值的问题啦 */
        if (min_stack.isEmpty() || val < min_stack.top()) {
            min_stack.push(val)
        } else {
            min_stack.push(min_stack.top())
        }
    }
    pop() {
        this.data_stack.pop()
        this.min_stack.pop()
    }
    min() {
        return this.min_stack.top()
    }
}

const min_stack = new MinStack()

min_stack.push(2)
console.log(min_stack.min());
min_stack.push(3)
console.log(min_stack.min());
min_stack.push(5)
console.log(min_stack.min());
min_stack.push(1)
console.log(min_stack.min());
min_stack.pop()
console.log(min_stack.min());
MinStack

@萍2樱释 ღ( ´・ᴗ・` )

打不死的小强
原文地址:https://www.cnblogs.com/mggahui/p/13380690.html