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


解题思路:

把每次的最小元素(之前的最小元素和新压入战的元素两者的较小值)都保存起来放到另外一个辅助栈里

假设每次都把最小元素压入辅助栈, 那么就能保证辅助栈的栈顶一直都是最小元素.当最小元素从数据栈内被弹出之后,同一时候弹出辅助栈的栈顶元素,此时辅助栈的新栈顶元素就是下一个最小值。

代码实现:

public class Test21 {
/**
* 定义栈的数据结构,请在该类型中实现一个可以得到校的最小元素的min函数。
* 在该栈中。调用pop、push 及min的时间复杂度都是0(1)
*
* @param <T> 泛型參数
*/
public static class StackWithMin<T extends Comparable<T>> {
// 数据栈,用于存放插入的数据
private Stack<T> dataStack;
// 最小数位置栈,存放数据栈中最小的数的位置
private Stack<Integer> minStack; // 构造函数
public StackWithMin() {
this.dataStack = new Stack<>();
this.minStack = new Stack<>();
} /**
* 出栈方法
* @return 栈顶元素
*/
public T pop() {
// 假设栈已经为空。再出栈抛出异常
if (dataStack.isEmpty()) {
throw new RuntimeException("The stack is already empty");
} // 假设有数据。最小数位置栈和数据栈必然是有同样的元素个数,
// 两个栈同一时候出栈
minStack.pop();
return dataStack.pop();
} /**
* 元素入栈
* @param t 入栈的元素
*/
public void push(T t) {
// 假设入栈的元素为空就抛出异常
if (t == null) {
throw new RuntimeException("Element can be null");
} // 假设数据栈是空的,仅仅接将元素入栈,同一时候更新最小数栈中的数据
if (dataStack.isEmpty()) {
dataStack.push(t);
minStack.push(0);
}
// 假设数据栈中有数据
else {
// 获取数据栈中的最小元素(未插入t之前的)
T e = dataStack.get(minStack.peek());
// 将t入栈
dataStack.push(t);
// 假设插入的数据比栈中的最小元素小
if (t.compareTo(e) < 0) {
// 将新的最小元素的位置入最小栈
minStack.push(dataStack.size() - 1);
} else {
// 插入的元素不比原来的最小元素小,复制最小栈栈顶元素,将其入栈
minStack.push(minStack.peek());
}
}
} /**
* 获取栈中的最小元素
* @return 栈中的最小元素
*/
public T min() {
// 假设最小数公位置栈已经为空(数据栈中已经没有数据了),则抛出异常
if (minStack.isEmpty()) {
throw new RuntimeException("No element in stack.");
} // 获取数据栈中的最小元素。而且返回结果
return dataStack.get(minStack.peek());
}
} public static void main(String[] args) {
StackWithMin<Integer> stack = new StackWithMin<>();
stack.push(3);
System.out.println(stack.min() == 3);
stack.push(4);
System.out.println(stack.min() == 3);
stack.push(2);
System.out.println(stack.min() == 2);
stack.push(3);
System.out.println(stack.min() == 2);
stack.pop();
System.out.println(stack.min() == 2);
stack.pop();
System.out.println(stack.min() == 3);
stack.push(0);
System.out.println(stack.min() == 0);
}
}

执行结果:

【剑指Offer学习】【面试题21:包括min 函数的栈】的更多相关文章

  1. 《剑指offer》面试题21—包含min函数的栈

    题目:定义栈数据结构,并在该数据结构中实现一个能获得栈最小元素的函数min.要求push,min,pop时间都是O(1). 思路:要用一个辅助栈,每次有新元素压栈时辅助栈压入当前最小元素:min函数直 ...

  2. 《剑指offer》面试题21 包含min函数的栈 Java版

    (min函数的作用是返回栈内最小值) 首先这个栈要具有普通栈所具有的push()和pop()方法,那么内部一定包含一个Stack.至于还要能实现min函数,而且还是在O(1)时间复杂度内,我们不得不考 ...

  3. 《剑指offer》面试题30. 包含min函数的栈

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

  4. 【剑指offer】面试题 21. 调整数组顺序使奇数位于偶数前面

    面试题 21. 调整数组顺序使奇数位于偶数前面

  5. 《剑指offer》面试题21. 调整数组顺序使奇数位于偶数前面

    问题描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分. 示例: 输入:nums = [1,2,3,4] 输出:[1,3,2,4] ...

  6. 剑指Offer:面试题21——包含min函数的栈(java实现)

    问题描述: 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数.在该栈中,调用min,push及pop的时间复杂度都是O(1). 思路:加入一个辅助栈用来存储最小值集合 (这里要注 ...

  7. (剑指Offer)面试题21:包含min函数的栈

    题目: 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数. 在该栈中,调用min,push,pop的时间复杂度都是O(1) 思路: 1.除了原来的栈s,增加一个辅助栈s_min,用 ...

  8. 剑指offer-面试题21.包含min函数的栈

    题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数. 在该栈中,调用min,push及pop的时间复杂度都是O(1). 这一题实际上需要一个辅助栈存储最小值: 1.在模板类定 ...

  9. (剑指Offer)面试题7:用两个栈实现队列

    题目: 用两个栈实现一个队列. 队列的声明如下:请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能. 思路: 根据栈的“先进后出”特点, ...

  10. 剑指offer笔记面试题1----赋值运算符函数

    题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数. class CMyString{ public: CMyString(char* pData = nullptr); CMyS ...

随机推荐

  1. 数据结构 单链表元素定位 PTA

    由于这个很简单,他也貌似没要判断溢出,取巧突破 #include<stdio.h> #include<malloc.h> #include<stdlib.h> // ...

  2. Python通过跳板机链接MySQL的一种方法

  3. RPA(Robotic Process Automation)的概要介绍

    最近因为公司业务的需要,开始关注RPA的内容,奈何国内相关的信息太少,只能硬着头皮啃英文了. 下面记录的内容作为学习笔记,有不对的地方请大家指教. 首先RPA(Robotic Process Auto ...

  4. Spring IOC容器分析(2) -- BeanDefinition

    上文对Spring IOC容器的核心BeanFactory接口分析发现:在默认Bean工厂DefaultListableBeanFactory中对象不是以Object形成存储,而是以BeanDefin ...

  5. SQL Server分组查询某最大值的整条数据(包含linq写法)

    想实现如下效果,就是分组后时间最大的那一条数据: 1.SQL SELECT * FROM ( SELECT * , ROW_NUMBER() OVER ( PARTITION BY RIP_GUID ...

  6. C#编程命名规范推荐

    1.用Pascal规则来命名方法和类型. Pascal 大小写形式是指名称中的单词的第一个字母大写public class DataGrid{public void DataBind(){ }} 2. ...

  7. C语言实现快速排序法(分治法)

    title: 快速排序法(quick sort) tags: 分治法(divide and conquer method) grammar_cjkRuby: true --- 算法原理 分治法的基本思 ...

  8. python进阶------进程线程(五)

    Python中的IO模型 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别 ...

  9. 结合程序崩溃后的core文件分析bug

    引言     在<I/O的效率比较>中,我们在修改图1程序的BUF_SIZE为8388608时,运行程序出现崩溃,如下图1:          图1. 段错误     一般而言,导致程序段 ...

  10. MySQL GTIDs(global transaction identifiers)

    1.如何定义和生成GTIDs 唯一性:在所有主从库都是唯一的,由二元组构成 每个事务和GTIDs之间都有1:1映射 GTID = source_id:transaction_id source_id标 ...