剑指offer-20、包含min函数的栈

题⽬描述

定义栈的数据结构,请在该类型中实现⼀个能够得到栈中所含最⼩元素的min 函数(时间复杂度为O(1) )。

此栈包含的⽅法有:

  • push(value) :将value 压⼊栈中
  • pop() :弹出栈顶元素
  • top() :获取栈顶元素
  • min() :获取栈中最⼩元素

思路及解答

双栈法(推荐,实现简单)

使用两个栈:

  1. 主栈:存储所有元素
  2. 辅助栈:存储当前主栈中的最小值

push ⼀个元素的时候,都需要push 进datas stack ,但是push 进⼊mins stack 需要满⾜条件:当前的mins stack 是空的,直接放⼊。或者当前的mins stack 的栈顶元素⼤于或者等于push 进来的值。

pop ⼀个元素的时候,如果栈为空则什么都不操作,如果栈不为空,则判断datas 的第⼀个元素是否和mins 的第⼀个元素相等。如果相等的话那么就需要将mins 和datas pop 出去第⼀个元素,否则只需要将datas 的第⼀个元素 pop 出去即可。

java 复制代码
public class Solution {
	private Stack<Integer> datas = new Stack<>();
	private Stack<Integer> mins = new Stack<>();

	/​**​
     * 将元素压入栈中
     * @param value 要压入的值
     */
	public void push(int node) {
		datas.push(node);
		// 如果辅助栈为空,或新值<=当前最小值,压入辅助栈
		if (mins.isEmpty()) {
			mins.push(node);
		} else {
			int min = mins.peek();
			if (node <= min) {
				mins.push(node);
			}
		}
	}
	
	public void pop() {
		if (datas.isEmpty()) {
			return;
		} else {
			int value = datas.peek();
			if (value == mins.peek()) {
				mins.pop();
			}
			datas.pop();
		}
	}
	
	public int top() {
		if(datas.isEmpty()){
			return -1;
		}
		return datas.peek();
	}
	
	public int min() {
		if(mins.isEmpty()){
			return -1;
		}
		return mins.peek();
	}
}
  • 时间复杂度: O(1)
  • 空间复杂度: O(n) ,借助了辅助栈。

差值法

使用一个栈和一个变量minValue

  1. 栈存储差值:存储元素与当前最小值的差值
  2. 更新最小值:当遇到更小值时,先存储当前差值(负值),再更新最小值
  3. 恢复前值pop时如果发现差值为负,说明此处发生过最小值更新,需要恢复前一个最小值
java 复制代码
public class Solution {
    private Stack<Long> stack = new Stack<>();; // 存储差值的栈
    private long minValue; // 当前最小值

    public void push(int value) {
        if (stack.isEmpty()) {
            minValue = value;
            stack.push(0L); // 差值为0
        } else {
            long diff = (long)value - minValue;
            stack.push(diff);
            // 如果差值为负,说明value是新的最小值
            if (diff < 0) {
                minValue = value;
            }
        }
    }

    public void pop() {
        if (stack.isEmpty()) {
            return;
        }
        long diff = stack.pop();
        // 如果差值为负,说明此处更新过最小值,需要恢复前一个最小值
        if (diff < 0) {
            minValue = minValue - diff;
        }
    }

    public int top() {
        if (stack.isEmpty()) {
           return;
        }
        long diff = stack.peek();
        // 如果差值为负,说明当前栈顶就是最小值
        if (diff < 0) {
            return (int)minValue;
        } else {
            return (int)(minValue + diff);
        }
    }

    public int min() {
        if (stack.isEmpty()) {
           return;
        }
        return (int)minValue;
    }
}
  • 时间复杂度:所有操作仍为O(1)
  • 空间复杂度:O(1)额外空间(仅一个变量),但栈存储的是差值而非原始值

需要考虑整数溢出问题(使用long存储差值)

相关推荐
一只幸运猫.12 小时前
JAVA后端面试题
java·开发语言
空中海12 小时前
第三章:Maven高级篇 — 插件开发与多模块工程
java·maven
秋912 小时前
TiDB 数据库全链路实战指南:从下载部署到 Java 高并发调优
java·数据库·tidb
JAVA面经实录91712 小时前
Java开发工程基础完整手册(企业实战完整版)
java·开发语言·git·ci/cd·svn·github·intellij idea
李艺为12 小时前
Fake Device Test作假屏幕分辨率分析
android·java
无敌的黑星星12 小时前
Spring @Transactional 注解全解析
java·数据库·oracle
xiaogg367812 小时前
spring oauth2 单点登录
java·vue.js·spring
c++之路12 小时前
C++ STL
java·开发语言·c++
白晨并不是很能熬夜12 小时前
【RPC】第 4 篇:服务发现 — Zookeeper + 缓存容错
java·后端·程序人生·缓存·zookeeper·rpc·服务发现
EvenBoy12 小时前
IDEA中使用CodeX
java·ide·intellij-idea