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

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

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

package algorithm.foroffer.top30;

import java.util.Stack;

/**
 * Created by liyazhou on 2017/5/27.
 * 面试题21:包含 min 函数的栈
 *
 * 题目:
 *      定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数,
 *      在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
 *
 * 问题:
 *      1. 栈的特性
 *      2. 求栈中的最小元素
 *
 * 思路:
 *      1. 使用索引栈
 *      2. 每次添加新元素时,在辅助栈中保存当前数据栈中的最小元素的位置
 */

/**
 * 对 T extends Comparable<T> 的理解:
 *
 * 1. T 必须实现 Comparable 接口,(并且这个接口类型是T)
 * 2. 需要给接口的抽象方法 compareTo 的参数类型为 T,也即是 compareTo(T t)
 * 比如 String implements Comparable<String>
 * 
 * @param <T>
 */
class StackWithMin<T extends Comparable<T>>{
    Stack<T> dataStack;   // 数据栈,保存压入的数据
    Stack<Integer> minIdxStack;  // 索引栈,该位置保存与数据栈的相同位置到栈底之间的最小元素的位置
    int minIdx;

    public StackWithMin(){
        dataStack = new Stack<>();
        minIdxStack = new Stack<>();
        minIdx = 0;
    }

    public void push(T element){
        if (element == null) throw new RuntimeException("the element is null.");
        dataStack.push(element);

        if (!minIdxStack.isEmpty()) {
            minIdx = dataStack.get(minIdxStack.peek()).compareTo(element) < 0 ? minIdx : dataStack.size()-1;
        }
        minIdxStack.push(minIdx);
    }

    public T pop(){
        if (dataStack.isEmpty()) throw new RuntimeException("The stack is already null.");
        minIdxStack.pop();
        return dataStack.pop();
    }

    public T min(){
        if (dataStack.isEmpty()) throw new RuntimeException("The stack is already null.");
        return dataStack.get(minIdxStack.peek());
    }

    @Override
    public String toString(){
        return dataStack.toString();
    }
}


public class Test21 {
    public static void main(String[] args){
        StackWithMin<Double> stack = new StackWithMin<>();
        stack.push(10.0);
        stack.push(15.0);
        stack.push(11.0);
        stack.push(2.0);
        stack.push(1.0);

        System.out.println(stack);
        System.out.println(stack.pop());
        System.out.println(stack);
        System.out.println(stack.min());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值