zoukankan      html  css  js  c++  java
  • 剑指offer-第四章解决面试题的思路(包含min函数的栈)

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

    思路:定义两个栈分别为dataStack和minStack,dataStack用来存放要放入栈中的数据,而minStack用来存放dataStack中的对应时刻的最小值。

    抽象问题具体化:如下图所示:

    C++代码:

    #include <stack>  
    #include <assert.h>  
    #include <stddef.h>  
      
    template <typename T> class StackWithMin  
    {  
    public:  
        StackWithMin(void) {}  
        virtual ~StackWithMin(void) {}  
      
        T& top(void);  
        const T& top(void) const;  
      
        void push(const T& value);  
        void pop(void);  
      
        const T& min(void) const;  
      
        bool empty() const;  
        size_t size() const;  
      
    private:  
        std::stack<T>   m_data;     // 数据栈,存放栈的所有元素  
        std::stack<T>   m_min;      // 辅助栈,存放栈的最小元素  
    };  
      
    template <typename T> void StackWithMin<T>::push(const T& value)  
    {  
        // 把新元素添加到辅助栈  
        m_data.push(value);  
      
        // 当新元素比之前的最小元素小时,把新元素插入辅助栈里;  
        // 否则把之前的最小元素重复插入辅助栈里  
        if(m_min.size() == 0 || value < m_min.top())  
            m_min.push(value);  
        else  
            m_min.push(m_min.top());  
    }  
      
    template <typename T> void StackWithMin<T>::pop()  
    {  
        //assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。
        assert(m_data.size() > 0 && m_min.size() > 0);  
        m_data.pop();  
        m_min.pop();  
    }  
      
      
    template <typename T> const T& StackWithMin<T>::min() const  
    {  
        assert(m_data.size() > 0 && m_min.size() > 0);  
      
        return m_min.top();  
    }  
      
    template <typename T> T& StackWithMin<T>::top()  
    {  
        return m_data.top();  
    }  
      
    template <typename T> const T& StackWithMin<T>::top() const  
    {  
        return m_data.top();  
    }  
      
    template <typename T> bool StackWithMin<T>::empty() const  
    {  
        return m_data.empty();  
    }  
      
    template <typename T> size_t StackWithMin<T>::size() const  
    {  
        return m_data.size();  
    } 
    void Test(char* testName, const StackWithMin<int>& stack, int expected)  
    {  
        if(testName != NULL)  
            printf("%s begins: ", testName);  
      
        if(stack.min() == expected)  
            printf("Passed.
    ");  
        else  
            printf("Failed.
    ");  
    }  
      
    int main()  
    {  
        StackWithMin<int> stack;  
      
        stack.push(3);  
        Test("Test1", stack, 3);  
      
        stack.push(4);  
        Test("Test2", stack, 3);  
      
        stack.push(2);  
        Test("Test3", stack, 2);  
      
        stack.push(3);  
        Test("Test4", stack, 2);  
      
        stack.pop();  
        Test("Test5", stack, 2);  
      
        stack.pop();  
        Test("Test6", stack, 3);  
      
        stack.pop();  
        Test("Test7", stack, 3);  
      
        stack.push(0);  
        Test("Test8", stack, 0);  
      
        return 0;  
    }  

    Java代码:

    import java.util.Stack;
    
    /**
     * 实现包含min函数的栈
     * @author DHC
     * @param <T>
     */
    public class MinInStack<T> {
    
        public static void main(String[] args) {
            MinInStack<Integer> newStack = new MinInStack<Integer>();
            newStack.push(4);
            System.out.println(newStack.min());
            newStack.push(6);
            System.out.println(newStack.min());
            newStack.push(2);
            System.out.println(newStack.min());
            newStack.push(5);
            System.out.println(newStack.min());
            newStack.pop();
            System.out.println(newStack.min());
            newStack.pop();
            System.out.println(newStack.min());
            newStack.push(1);
            System.out.println(newStack.min());
        }
        
        public Stack<T> dataStack = new Stack<T>();
        
        public Stack<T> minStack = new Stack<T>();
        
        public void pop() {
           if(dataStack.size()>0&&minStack.size()>0)
           {
                dataStack.pop();
                minStack.pop();
           }
        }
        
        public void push(T item) {
            dataStack.push(item);
            if(minStack.size()==0||compare(minStack.peek(),item))
            {
                minStack.push(item);
            }
            else
                minStack.push(minStack.peek());
        }
        
        public T peek() {
            
            return dataStack.peek();
        }
      
        public T min() {
           return minStack.peek();
        }
        
        public boolean isEmpty() {
            return dataStack.isEmpty();
        }
        public int size(){
            return dataStack.size();
        }
    
        /**
         * 泛型元素的比较方法
         * @param minData
         * @param item
         * @return true 代表当前元素小于之前的最小元素
         */
       
        public boolean compare(T minData, T item) {
            // 这儿不同的泛型类型可以用不同的方式实现
            // 如果写成通用代码泛型之间应该肿么比较大小呢?是不是可以让泛型都继承某一接口呢?
            int a = (Integer) minData;
            int b = (Integer) item;
            if(a > b) {
                return true;
            } else {
                return false;
            }
        }
    }
  • 相关阅读:
    转载 | float 清除浮动的7种方法
    转载 | CSS图片下面产生间隙的 6种解决方案
    (转载)内联元素设置宽高问题
    HTML/CSS:display:flex 布局教程
    HTML/CSS:block,inline和inline-block概念和区别
    上传文件
    分页查询 模糊查询 合体查询
    repeater的command用法
    窗体内的控制 跨窗体控制
    webform 跨窗体传值
  • 原文地址:https://www.cnblogs.com/hupp/p/4595858.html
Copyright © 2011-2022 走看看