【栈,队列,递归,循环】用两个栈实现队列,斐波那契数列题目变种

版权声明:本文为博主原创学习笔记,如需转载请注明来源。 https://blog.csdn.net/SHU15121856/article/details/82377505

栈和队列问题

栈的特点是后进先出,队列的特点是先进先出。通常栈是不考虑排序的数据结构,而队列可能存在排序问题。

面试题9:用两个栈实现队列

在一个自定义的队列类中维护了两个STL栈,实现在队列尾部插入结点和在队列头部删除结点的两个方法。

在插入时都push到一个栈A里,在删除时如果栈B里有就从栈B里pop一个,否则把栈A的全倒进去,再从栈B里pop一个。

#include<bits/stdc++.h>
using namespace std;

//泛型队列类
template <typename T> class CQueue {
    public:
        CQueue(void);
        ~CQueue(void);

        //在队列末尾添加一个元素
        void appendTail(const T& node);

        //在队列头部删除一个元素
        T deleteHead();

    private:
        //提供两个STL栈
        stack<T> stack1;
        stack<T> stack2;
};

//构造函数
template <typename T> CQueue<T>::CQueue(void) {
}

//析构函数
template <typename T> CQueue<T>::~CQueue(void) {
}

//在逻辑队尾添加一个元素
template<typename T> void CQueue<T>::appendTail(const T& element) {
    stack1.push(element);//直接添加到A栈里
}

//在逻辑队头删除一个元素
template<typename T> T CQueue<T>::deleteHead() {
    //如果B栈里没有东西
    if(stack2.size()<= 0) {
        //对于A栈里的所有元素
        while(stack1.size()>0) {
            T& data = stack1.top();//这里是取栈顶元素,不然一会pop掉就没了
            stack1.pop();//弹出A栈的元素
            stack2.push(data);//压入B栈
        }
        //至此,A栈里的元素反向压入了B栈
    }

    //如果B栈里还是没有东西,这时A栈里也一定没有了,说明队列就是为空
    if(stack2.size() == 0)
        throw new exception();

    //否则从B栈中弹出栈顶元素,即是队列的头元素
    T head = stack2.top();//先取
    stack2.pop();//再弹

    return head;//返回刚刚删除的元素 
}

int main(int argc, char* argv[]) {
    //泛型擦除为char,建立自定义队列
    CQueue<char> queue;

    //在队列中添加元素
    queue.appendTail('a');
    queue.appendTail('b');
    queue.appendTail('c');

    try {
        //删除与测试
        char head = queue.deleteHead();
        cout<<"head="<<head<<endl;

        head = queue.deleteHead();
        cout<<"head="<<head<<endl;
    } catch(exception& exception) {
        cerr<<"queue is empty"<<endl;
    }
    return 0;
}

递归和循环问题

通常递归的代码会比较简洁,但递归由于是函数调用自身,会有不小的时间和空间的消耗。另外,递归中很多计算都是重复的,从而对性能有很大的负面影响。另外,递归中有可能很多计算是重复的,对性能带来很大影响。

面试题10:斐波那契数列

当n=0时,f(n)=0;当n=1时,f(n)=1;此后f(n)=f(n-1)+f(n-2)。求斐波那契数列的第n项。

这题不必多说了,递归和循环的解法都很普通。

斐波那契数列的变种

特别记录下书上的两道变种题。

青蛙跳台阶问题

一只青蛙一次能跳1阶或者2阶,跳上n级台阶有几种跳法。

设所求为f(n),第一次只能跳1阶或者2阶,因此f(n)=f(n-1)+f(n-2),其中f(1)=1,f(2)=2,本质就是斐波那契数列问题,只是初始项不同。

矩形全覆盖问题

用若干1x2的矩形横竖去覆盖2x8的矩形,小矩形间不可重叠,问有多少种方法。

假设所求是f(8):
这里写图片描述
在覆盖最左上角时,就只有两种选择,横着放或者竖着放。竖着放,右边就是剩f(7):
这里写图片描述
横着放,那么下面的两个各自也只有横着放这一种选择,所以能变的只有右边的f(6):
这里写图片描述
所以f(8)=f(7)+f(6),这个仍然是斐波那契数列问题。且f(1)=1,f(2)=2。

扫描二维码关注公众号,回复: 3052770 查看本文章

猜你喜欢

转载自blog.csdn.net/SHU15121856/article/details/82377505