zoukankan      html  css  js  c++  java
  • 一道惰性更新策略的题目

    题目来自《程序员面试金典》栈排序

    题目描述:

    编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。
    该栈支持如下操作:push、pop、peek 和 isEmpty。当栈为空时,peek 返回 -1。
    
    示例1:
    
     输入:
    ["SortedStack", "push", "push", "peek", "pop", "peek"]
    [[], [1], [2], [], [], []]
     输出:
    [null,null,null,1,null,2]
    示例2:
    
     输入: 
    ["SortedStack", "pop", "pop", "push", "pop", "isEmpty"]
    [[], [], [], [1], [], []]
     输出:
    [null,null,null,null,null,true]
    说明:
    
    栈中的元素数目在[0, 5000]范围内。
    

    解题思路:

    题目的描述是:实现一个API:SortedStack,称为有序栈,内部使用两个栈来进行实现。
    一般的思路是:

    1. mainStk维护一个有序的栈,每次push前,先把mainStk栈顶小于当前val的值移动到helpStk
    2. valpushmainStk
    3. 最后把helpStk中的元素push到mainStk中。

    思考下是否可以继续优化,
    当我们连续push某个值时,其实每次都需要把若干个元素暂时转移到helpStack中。
    其实这个过程可以优化为,
    当我们push这个值后,不要马上把mainStack恢复到有序的状态,而是根据下一个值的大小,来动态调整,使之mainStack继续满足可以push的状态。比如连续push相同值时,就可以在上个状态结束后,继续push。当我们想要取出最小值时,才将mainStack恢复到有序栈的状态。取出栈顶元素就是最小值。
    这种方法其实是一种惰性更新的策略,也就是在真正需要的时候,才继续排序或者转移。类似于linux中的写时复制,在创建一个子进程时,没有马上复制父进程中的内存空间的数据。子进程在只读的情况下,可以沿用父进程中的内存数据。当子进程的内存空间的数据真正改变需要写入的时候,才进行复制。一般称为copy-on-write技术。这种技术提高了linux中进程创建的效率。

    解题代码:

    push的时候,进行状态调整,使之满足使其满足 helpStack.top() <= val <= mainStack.top(),
    然后helpStackmainStack栈中的元素分别是有序的,mainStack栈中的元素是升序的,helpStack栈中的元素是降序的。此时,可以将al值push到mainStack中,则通过这两个栈维护的整个区间元素是有序的。

    void push(int val) {
        while(st1.size() && st1.top() < val) {
            st2.push(st1.top());
            st1.pop();
        }
    
        while(st2.size() && st2.top() > val) {
            st1.push(st2.top());
            st2.pop();
        }
    
        st1.push(val);
    }
    

    peek时,将helpStack元素pushmainStack中,mainStack是有序的,返回栈顶元素即可。

        int peek() {
           while(st2.size()) {
                st1.push(st2.top());
                st2.pop();
            }
    
            if(st1.size()) {
                return st1.top();
            }
    
            return -1;
        }
    
  • 相关阅读:
    微软铁杆兄弟诺基亚开发基于Linux的手机
    Linux目录递归改变文件名大小写
    boa-0.94.13 移植到 ARM
    LINUX如何设置只允许SSH登陆?
    9.4. 使用 I/O 内存
    I-O 端口和 I-O 内存
    Linux 的虚拟文件系统--各结构之间的联系
    Linux 系统调用
    【poj2528】Mayor's posters
    【poj3225】Help with Intervals
  • 原文地址:https://www.cnblogs.com/shijiashuai/p/14414350.html
Copyright © 2011-2022 走看看