/* 日期:2019.7.22
* 作者:***
* 功能:剑指offer 题目20
*
* =====================================================
* 问题描述:
* 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数
* 要求:(时间复杂度应为O(1))。
*
* ======================================================
* 思路详解:
* 这道题目,说实在的,仅根据剑指offer的题目描述,我看了半天没明白题目什么意思。
* 最后,得出个人对题目的理解:
* 题目最大的要求就是,实现个人实现一个栈,并且,有个min函数,得到其栈中最小值
* 那么,时间复杂的为O(1),也就是栈中内部,必须时刻维护这一个最小值
* 当放进元素和取出元素的时候,维护这这个最小值!以达到要求的O(1)的时间复杂度。
*
* 理解了题目,再来考虑思路:
* 首先,最简单的考虑为,维护一个min值,每次进栈的时候,新元素与min进行比较
* 从而改变或维护原来的min值,顺着这个思路,我们发现,当出栈的时候,就有问题了
* 出栈的时候,怎么维护min值,假如,出栈的值等于min值,我们是改变min值吗?
* 答案是不一定的,万一还有元素等于min值呢?假如确定了没有元素等于min值了,那接
* 下来min值又应该等于多少呢?
* 至此,我们发现这个思路是行不通的,但是也给了我们启发,那就是进栈简单,如何保证出栈的思路?
* 这就启发我们,还要找到一种逻辑去维护一个min值的序列,依次大小保证!
*
* 所以本题采用一个辅助栈来维护min的序列,之所以用栈维护,是因为,栈保证了其先进后出的顺序
* 思路如下:
* 当向栈中放进数据的时候,判断当前元素node与栈中原来min值的相对大小。
* 如果,node大于min,则直接压入即可,辅助栈不需要改变
* 如果,node小于min,则需要改变min值为node,并且辅助栈压入这个node值,保证辅助栈的栈顶一直是min
* 如果,node等于min,仔细想想,其实和node小于min的操作一致
*
* 以上思路保证了:
* 进栈就不多说了,很简单,也很容易理解;
* 出栈的时候,解决了我们上述分析的两个问题:
* 1.出栈的值等于min值,我们是改变min值吗?
* 2.假如确定了没有元素等于min值了,那接下来min值又应该等于多少呢?
*
* 因为,我们辅助栈其实是种维护了某个特定序列的min值。
* 当出栈元素等于min值的时候,无论剩余栈中元素有没有等于min值的了,我们都能确定
* 新的min值就等于辅助栈中栈顶的下一元素。
* 很简单,因为进栈进了几次,我们辅助栈也进了几次!
* 所以,每出一次栈,我们辅助栈也减少了一次当前值。
* 很巧妙的思想!其实,辅助栈中从上到小的序列是严格的非递减序列,
* 始终保证了剩余元素的min值就是辅助栈的栈顶值!
*
* */
package com.*******;
import java.util.*;
import java.util.Stack; //使用java栈
//根据题目要求,是要构造出一个栈的数据结构,实现其方法min,求最小值
public class Main11 {
private Stack<Integer> stack1 = new Stack<Integer>(); //实现要求的栈结构
private Stack<Integer> stack2 = new Stack<Integer>(); //辅助栈去维护min值的相对序列
int minValue = Integer.MAX_VALUE;
public void push(int node) { //放进栈中
stack1.push(node); //进栈操作,实现栈的基本操作
if (node <= minValue) { //比较新元素与原栈中的min值的相对大小
minValue = node; //改变min值
stack2.push(minValue); //辅助栈压入min值,注意这一步是整个算法的核心,保证了出栈的操作正确
}
}
public void pop() { //取出元素
if(stack1.isEmpty()) //栈为空,抛出异常
throw new RuntimeException();
int top = stack1.peek(); //先取出栈顶,用于判断辅助栈是否需要改变
stack1.pop(); //出栈操作
if(stack2.peek() == top) //判断当前删除元素的值是否等于min
{
stack2.pop(); //删除元素等于min,那么辅助栈栈顶删除一次
if(stack2.isEmpty())
minValue = Integer.MAX_VALUE;
else
minValue = stack2.peek();
}
}
public int top() { //得到栈顶元素
return stack1.peek();
}
public int min() { //题目所求,得到其所含最小值
return minValue;
}
//主函数,程序代码测试入口
public static void main(String args[])
{
Main11 main11 = new Main11();
System.out.println("当前栈中最小值为:"+main11.minValue);
main11.push(3);
System.out.println("当前栈中最小值为:"+main11.minValue);
main11.push(4);
System.out.println("当前栈中最小值为:"+main11.minValue);
main11.push(2);
System.out.println("当前栈中最小值为:"+main11.minValue);
main11.push(3);
System.out.println("当前栈中最小值为:"+main11.minValue);
main11.pop();
System.out.println("当前栈中最小值为:"+main11.minValue);
main11.pop();
System.out.println("当前栈中最小值为:"+main11.minValue);
main11.pop();
System.out.println("当前栈中最小值为:"+main11.minValue);
main11.push(0);
System.out.println("当前栈中最小值为:"+main11.minValue);
}
}
剑指Offer——题目20
猜你喜欢
转载自blog.csdn.net/romantic_jie/article/details/96885267
今日推荐
周排行