数据结构-栈和队列

用两个栈实现队列


用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

class Solution
{
public:
     // 先将1个数据压入stack1中,然后再从stack1中取出压入stack2中
    void push(int node) {
        stack1.push(node);
    }

    int pop() {

        int node;
        if (stack2.empty()) {
            while (!stack1.empty()) {
                node = stack1.top();
                stack1.pop();
                stack2.push(node);
            }
        }
        node = stack2.top();
        stack2.pop();
        return node;
    }



private:
    stack<int> stack1;
    stack<int> stack2;
};

斐波那契数列(不要使用递归,使用循环方法)


大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。

class Solution {
public:
    int Fibonacci(int n) {

        int result[2] = {0,1};
    if (n < 2) {
        return result[n];
    }
    long long fibNMinusOne = 1;
    long long fibNMinusTwo = 0;
    long long fibN = 0;
    for (unsigned int i = 2; i <= n; i++) {

        fibN = fibNMinusOne + fibNMinusTwo;
        fibNMinusTwo = fibNMinusOne;
        fibNMinusOne = fibN;
    }
    return fibN;

    }
};

跳台阶


一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

class Solution {
public:
    int jumpFloor(int number) {
       int result[3] = {0,1,2};
    if (number < 3) {
        return result[number];
    }
    long long fibNMinusOne = 2;
    long long fibNMinusTwo = 1;
    long long fibN = 0;
    for (unsigned int i = 3; i <= number; i++) {

        fibN = fibNMinusOne + fibNMinusTwo;
        fibNMinusTwo = fibNMinusOne;
        fibNMinusOne = fibN;
    }
    return fibN;
    }
};

变态跳台阶


一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

class Solution {
public:
    int jumpFloorII(int number) {
        if (number == 0) {
        return 0;
    }else if (number == 1){
        return 1;
    }
    else{
        int count = 1;
        for (int i = 2; i <= number; i++) {
            count = 2* count;
        }
        return count;
    }
    }
};

矩形覆盖(斐波那契数列)


我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

class Solution {
public:
    int rectCover(int number) {
        int result[3] = {0,1,2};
    if (number < 3) {
        return result[number];
    }
    long long fibNMinusOne = 2;
    long long fibNMinusTwo = 1;
    long long fibN = 0;
    for (unsigned int i = 3; i <= number; i++) {

        fibN = fibNMinusOne + fibNMinusTwo;
        fibNMinusTwo = fibNMinusOne;
        fibNMinusOne = fibN;
    }
    return fibN;

    }
};

二进制中1的个数


输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

class Solution {
public:
     int  NumberOf1(int n) {
         int count = 0;
        unsigned int flag = 1;
        while (flag) {
            if (n & flag) {
                count++;
            }
            flag = flag << 1;
        }
        return count;
     }
};

包含min函数的栈


定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。

class Solution {
public:
    stack<int> dataStack,minStack;
    void push(int value) {

    // 将最新的元素压入数据栈中
    dataStack.push(value);
    // 该元素与最小栈先进行比较
    if (!minStack.empty()) {
        // 取出最小栈的最顶值
        int node = minStack.top();
        if (value <= node) {
            // 压入最小栈
            minStack.push(value);
        }else{
            // 继续压入本栈中的栈顶值
            minStack.push(minStack.top());
        }
    }else{
        minStack.push(value);
    }

}
void pop() {
    dataStack.pop();
    minStack.pop();
}
int top() {

    return dataStack.top();

}
int min() {

    return minStack.top();
}

};

栈的压入、弹出序列


输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

思路:解决这个问题很直观的想法就是建立一个辅助栈。总结上述入栈、出栈的过程,我们可以找到判断一个序列是不是栈的弹出序列的规律:如果下一个弹出的数字刚好是栈顶数字,那么直接弹出。如果下一个弹出的数字不在栈顶,我们把压栈数列中还没有入栈的数字压入辅助栈,知道把下一个需要弹出的数字压入栈顶为止。如果所有的数字都压入栈了仍然没有找到下一个弹出的数字,那么该序列不可能是一个弹出序列。

/*思路:先循环将pushA中的元素入栈,遍历的过程中检索popA可以pop的元素
**如果循环结束后栈还不空,则说明该序列不是pop序列。
*/
class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {

        bool isPopOrder = false;
    stack<int> stack;
    if (pushV.size() == 0 || popV.size() == 0 || pushV.size() != popV.size()) {
        return isPopOrder;
    }

    int index = 0;
    for (int i = 0; i < pushV.size(); i++) {
        // 先每个元素压栈
        stack.push(pushV[i]);

        // 每次压栈后,判断下出栈的首元素是不是在栈顶,如果是在栈顶,则直接弹出栈
        while (popV[index] == stack.top()) {
            // 如果栈顶元素是出栈的首元素,直接弹出
            stack.pop();
            index++;
            if (index == popV.size()) {
                if (stack.empty()) {
                    isPopOrder = true;
                    return isPopOrder;
                }else{
                    isPopOrder = false;
                    return isPopOrder;
                }
            }
        }
    }

    if (stack.empty()) {
        isPopOrder = true;
    }
    return isPopOrder;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值