leetcode题目之Min Stack

题目

Memory Limit Exceeded

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

push(x) – Push element x onto stack. pop() – Removes the element on top of the stack. top() – Get the top element. getMin() – Retrieve the minimum element in the stack.

错误代码

看到此题目,以为是用实现一个简单的栈结构,于是就直接写下了如下代码,采用了双向链表的方式来实现:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class MinStack {
public:
	struct Node
	{
		int data;
		Node *next;
		Node *pre;
		Node() : next(NULL),pre(NULL) {}; 
	};
	
	MinStack()
	{
		header = new Node();
		tail = header;
	}
	
    void push(int x) {
        Node *node = new Node();
		node->data = x;
		node->pre = tail;
		tail->next = node;
		tail = node;
    }

    void pop() {
        Node *pre = tail->pre;
		delete tail;
		tail = pre;
		tail->next = NULL;
    }

    int top() {
		if (tail == header)
		{
			return -1;
		}
        return tail->data;
    }

    int getMin() {
		Node *begin = header->next;
		int min = INT_MIN;
        while(begin)
		{
			if (min > begin->data)
			{
				min = begin->data;
			}
			begin = begin->next;
		}
		return min;
    }
	
private:
	Node *header;
	Node *tail;
};

提交后提示Memory Limit Exceeded错误,开始考虑是不是双向链表占用的空间过多。

正确代码

仔细看题目后发现retrieving the minimum element in constant time,即时间复杂度为O(1),上述实现代码时间复杂度为O(n),明显不符合要求。看来理解题目有误,不是为了实现栈类,而是为了利用数据结构解决获取最小值问题。

经过考虑后可以通过在类内部维护存储最小值的栈来解决,存储最小值的栈除了需要存储最小值外,还需要维护最小值个数。

实现代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class MinStack {
	struct MinUnit
	{
		int count;
		int value;
		MinUnit(int count, int value) : count(count), value(value) {};
	};
public:
    void push(int x) {
        data_stack.push(x);
		if (min_stack.empty() || x < min_stack.top()->value)
		{
			MinUnit *p_unit = new MinUnit(1, x);
			min_stack.push(p_unit);
		}
		else if (x == min_stack.top()->value)
		{
			min_stack.top()->count++;
		}
    }

    void pop() {
        if (data_stack.top() == min_stack.top()->value)
		{
			if (min_stack.top()->count == 1)
			{
				MinUnit *punit = min_stack.top();
				min_stack.pop();
				delete punit;
			}
			else
			{
				min_stack.top()->count--;
			}
		}
		data_stack.pop();
    }

    int top() {
		return data_stack.top();
    }

    int getMin() {
		return min_stack.top()->value;
    }
	
private:
	std::stack<int> data_stack;
	// 最小栈,为了便于修改栈单元中的count值,采用存储指针方式
	std::stack<MinUnit*> min_stack;
};