给定一个非空整数数组c语言,LeetCode 155. 最小栈

该博客详细介绍了LeetCode 155题的解决方案,即设计一个在常数时间内能检索到最小元素的栈。文中提出了三种不同的实现思路:使用双栈、构造链表节点以及使用双数组记录。每种方法的时间复杂度均为O(1),空间复杂度为O(n)。博主通过Java代码展示了这三种方法的具体实现,并在每个实现后附上了相应的算法复杂度分析。
摘要由CSDN通过智能技术生成

LeetCode 155. 最小栈

题目

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

push(x) —— 将元素 x 推入栈中。

pop() —— 删除栈顶的元素。

top() —— 获取栈顶元素。

getMin() —— 检索栈中的最小元素。

示例:

输入:

["MinStack","push","push","push","getMin","pop","top","getMin"]

[[],[-2],[0],[-3],[],[],[],[]]

输出:

[null,null,null,null,-3,null,0,-2]

解释:

MinStack minStack = new MinStack();

minStack.push(-2);

minStack.push(0);

minStack.push(-3);

minStack.getMin(); --> 返回 -3.

minStack.pop();

minStack.top(); --> 返回 0.

minStack.getMin(); --> 返回 -2.

提示:

pop、top 和 getMin 操作总是在 非空栈 上调用。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/min-stack

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

本题核心要解决的是如何记录最小值的问题;

思路1-使用双栈,其中一个为单调递减栈,记录最小值;

步骤:

一个栈正常记录数据,一个栈为单调递减栈,只记录比当前栈顶元素小或等于的值(连续相等的值都需要记录,若只记录一次,同值出栈后最小值记录会丢失);

出栈时若为当前最小栈的栈顶值则最小栈也出栈;

算法复杂度:

时间复杂度: $ {\color{Magenta}{\Omicron\left(1\right)}} $

空间复杂度: $ {\color{Magenta}{\Omicron\left(n\right)}} $

思路2-自己构造节点链表

步骤:

定义节点,头节点总记录当前值以及当前最小值;

入栈时更新头结点和最小值,出栈时直接更新头结点为其next即可;

算法复杂度:

时间复杂度: $ {\color{Magenta}{\Omicron\left(1\right)}} $

空间复杂度: $ {\color{Magenta}{\Omicron\left(n\right)}} $

思路3-使用双数组/list记录

步骤:

定义存储数据和最小值的数组,注意最小值的初值处理;

入栈出栈等价于改变数组的index,注意数组的扩容问题,此处扩容为原数组的1.5倍;

算法复杂度:

时间复杂度: $ {\color{Magenta}{\Omicron\left(1\right)}} $

空间复杂度: $ {\color{Magenta}{\Omicron\left(n\right)}} $

算法源码示例

package leetcode;

import java.util.Arrays;

import java.util.Stack;

/**

* @author ZhouJie

* @date 2020年5月3日 下午4:00:43

* @Description: 155. 最小栈

*

*/

public class LeetCode_0155 {

}

/**

* @author ZhouJie

* @date 2020年5月3日 下午3:23:07

* @Description: 1-两个栈,一个作辅助栈存单调递减值;

*

*/

class MinStack_0155_1 {

private Stack data;

private Stack min;

/** initialize your data structure here. */

public MinStack_0155_1() {

this.data = new Stack();

this.min = new Stack();

}

public void push(int x) {

data.push(x);

if (min.isEmpty() || x <= min.peek()) {

min.push(x);

}

}

public void pop() {

if (!data.isEmpty()) {

if (min.peek().intValue() == data.pop().intValue()) {

min.pop();

}

}

}

public int top() {

if (data.isEmpty()) {

return -1;

}

return data.peek();

}

public int getMin() {

if (min.isEmpty()) {

return -1;

}

return min.peek();

}

}

/**

* @author ZhouJie

* @date 2020年5月3日 下午3:23:47

* @Description: 2-构造链表

*

*/

class MinStack_0155_2 {

private Node head;

/** initialize your data structure here. */

public MinStack_0155_2() {

}

public void push(int x) {

if (head == null) {

head = new Node(x, x, null);

} else {

head = new Node(x, Math.min(x, head.min), head);

}

}

public void pop() {

head = head.next;

}

public int top() {

return head.val;

}

public int getMin() {

return head.min;

}

private static class Node {

int val;

int min;

Node next;

public Node(int val, int min, Node next) {

this.val = val;

this.min = min;

this.next = next;

}

}

}

/**

* @author ZhouJie

* @date 2020年5月3日 下午3:45:08

* @Description: 3-使用数组保存数据

*

*/

class MinStack_0155_3 {

private int[] data;

private int[] min;

private int head;

private int cap = 1024;

/** initialize your data structure here. */

public MinStack_0155_3() {

this.head = 0;

this.data = new int[cap];

this.min = new int[cap];

min[0] = Integer.MAX_VALUE;

}

public void push(int x) {

if (head == cap - 2) {

// 扩容至原来的1.5倍

cap = cap + (cap >> 1);

data = Arrays.copyOf(data, cap);

min = Arrays.copyOf(min, cap);

}

data[++head] = x;

min[head] = (head == 1) ? x : Math.min(min[head - 1], x);

}

public void pop() {

if (head > 0) {

head--;

}

}

public int top() {

return head > 0 ? data[head] : -1;

}

public int getMin() {

return head > 0 ? min[head] : -1;

}

}

/**

* Your MinStack object will be instantiated and called as such:

* MinStack obj = new MinStack();

* obj.push(x);

* obj.pop();

* int param_3 = obj.top();

* int param_4 = obj.min();

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值