《剑指offer》第三十一题:栈的压入、弹出序列

// 面试题31:栈的压入、弹出序列
// 题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是
// 否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1、2、3、4、
// 5是某栈的压栈序列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列,但
// 4、3、5、1、2就不可能是该压栈序列的弹出序列。

#include <cstdio>
#include <stack>

bool IsPopOrder(const int* pPush, const int* pPop, int nLength)
{
    bool isPossible = false;

    //鲁棒性检测
    if (pPush != nullptr && pPop != nullptr && nLength > 0)
    {
        const int* pNextPush = pPush; //const int* 指地址指向的数据是const
        const int* pNextPop = pPop;

        std::stack<int> stackData; //辅助栈

        while (pNextPop - pPop < nLength) //弹出序列匹配完成跳出
        {
            //此循环按照压入序列顺序压入数字入栈
            //直到栈顶元素为下一个需要弹出的元素
            while (stackData.empty() || stackData.top() != *pNextPop) 
            {
                if (pNextPush - pPush == nLength) //如果压入栈为空, 跳出
                    break;

                //压入压入序列元素
                stackData.push(*pNextPush);
                ++pNextPush;
            }

            //压入数据后栈顶不是弹出元素
            if (stackData.top() != *pNextPop)
                break;

            stackData.pop();
            ++pNextPop;
        }

        if (stackData.empty() && pNextPop - pPop == nLength)
            isPossible = true;
    }
    return isPossible;
}
// ====================测试代码====================
void Test(const char* testName, const int* pPush, const int* pPop, int nLength, bool expected)
{
    if (testName != nullptr)
        printf("%s begins: ", testName);

    if (IsPopOrder(pPush, pPop, nLength) == expected)
        printf("Passed.\n");
    else
        printf("failed.\n");
}

void Test1()
{
    const int nLength = 5;
    int push[nLength] = { 1, 2, 3, 4, 5 };
    int pop[nLength] = { 4, 5, 3, 2, 1 };

    Test("Test1", push, pop, nLength, true);
}

void Test2()
{
    const int nLength = 5;
    int push[nLength] = { 1, 2, 3, 4, 5 };
    int pop[nLength] = { 3, 5, 4, 2, 1 };

    Test("Test2", push, pop, nLength, true);
}

void Test3()
{
    const int nLength = 5;
    int push[nLength] = { 1, 2, 3, 4, 5 };
    int pop[nLength] = { 4, 3, 5, 1, 2 };

    Test("Test3", push, pop, nLength, false);
}

void Test4()
{
    const int nLength = 5;
    int push[nLength] = { 1, 2, 3, 4, 5 };
    int pop[nLength] = { 3, 5, 4, 1, 2 };

    Test("Test4", push, pop, nLength, false);
}

// push和pop序列只有一个数字
void Test5()
{
    const int nLength = 1;
    int push[nLength] = { 1 };
    int pop[nLength] = { 2 };

    Test("Test5", push, pop, nLength, false);
}

void Test6()
{
    const int nLength = 1;
    int push[nLength] = { 1 };
    int pop[nLength] = { 1 };

    Test("Test6", push, pop, nLength, true);
}

void Test7()
{
    Test("Test7", nullptr, nullptr, 0, false);
}

int main(int argc, char* argv[])
{
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();
    Test6();
    Test7();

    return 0;
}
测试代码

分析:举例子分析复杂问题来捋顺思路。

注意:pNextPush - pPush == nLength 中,同一空间内两个地址之差为 p - q = (p地址 - q地址) / sizeof(int)。代码中pPush溢出后相减为5。

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        
        bool isPossible = false;
        int nLength = pushV.size();
        int popLength = popV.size();
        
        if (pushV.size() > 0 && popV.size() > 0 && nLength == popLength && nLength > 0)
        {
            int pushNext = 0;
            int popNext = 0;
            std::stack<int> stackData;
            
            while (popNext < nLength) //弹出序列匹配完成跳出
            {
                while (stackData.empty() || stackData.top() != popV[popNext]) //压入元素入栈直到栈顶为弹出元素
                {
                    if (pushNext == nLength) //压入序列为空
                        break;
                    
                    stackData.push(pushV[pushNext]);
                    ++pushNext;
                }
                if (stackData.top() != popV[popNext]) //栈顶元素不为下一个弹出序列
                    break;
                    
                stackData.pop();
                popNext++;
            }
            
            if (stackData.empty() && popNext == nLength)
                isPossible = true;
        }
        return isPossible;
    }
};
牛客网提交代码

 

posted @ 2020-03-30 17:24  源周率  阅读(157)  评论(0编辑  收藏  举报