剑指 31 栈的压入、弹出序列【贪心算法】

65 篇文章 1 订阅

剑指 31 栈的压入、弹出序列 【贪心算法】

原题目

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof

示例 1:

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

示例 2:

输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。

考查知识点

贪心

贪心算法现在还不是很了解,看了力扣题解才知道这里用到了贪心


自己的第一遍解法

在纸上写写画画,发现下一个弹出的元素只有两种情况 {当前栈顶元素pushed中的下一个数字}。基于这样的思路歇了如下代码:

class Solution_failed {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        if (pushed.empty() || popped.empty())
            return false;

        vector<int> s;
        //1)将pushed数组元素逐个加入栈中,直到遇到poped第一个元素
        while (popped[0] != pushed[0] && !pushed.empty())
        {
            s.push_back(pushed[0]);
            pushed.erase(pushed.begin());
            continue;
        }
        s.push_back(pushed[0]);
        pushed.erase(pushed.begin());

        if (s.empty())
            return false;

        while (!popped.empty())
        {
            //2) pushed.back() == popped[popIndex]
            //   检查poped[新的popIndex]与s.back()是否一样
            s.pop_back();
            popped.erase(popped.begin());
            if (popped[0] != s.back() && !pushed.empty()) {
                s.push_back(pushed[0]);
                pushed.erase(pushed.begin());
                if (popped[0] != s.back())
                    return false;
            }
            if (popped[0] != s.back() && pushed.empty())
                return false;

        }
        return true;
    }
};

但是这样的思路被示例给局限住了,下一个弹出的元素应该是这两种情况 {当前栈顶元素pushed中接下来的某个数字}


好的解法

参考:力扣题解图解 模拟入栈操作,贪心算法

这里就是模拟了入栈和出栈(一边入栈还要考虑是否出栈)的实际操作。pushed中新元素的每次入栈,都要判断栈顶元素是否就是poped[j],如果满足该条件,说明可以弹出栈顶元素,并且弹出栈顶元素后还要循环判断最新的栈顶元素是否与下一个poped[j]相同,满足条件就接着弹出栈顶元素。

class Solution
{
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped)
    {
        stack<int> s;
        int n = popped.size();
        int j = 0;      //指向poped数组当前元素的下标
        for (int& i : pushed)
        {
            s.push(i);
            while (!s.empty() && j<n && s.top()==popped[j])
            {
                s.pop();
                ++j;
            }
        }
        return s.empty();
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值