螺旋矩阵+栈的压入弹出顺序

题目描述

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 1:


输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:


输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
 

提示:

m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100

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

示例 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 之前弹出。
 

提示:

0 <= pushed.length == popped.length <= 1000
0 <= pushed[i], popped[i] < 1000

思路一---螺旋矩阵        

 我们无非是将最小的圈分为奇数圈和偶数圈,前者循环(N-1)/2次,后者循环N/2次,对于奇数圈我们在基本遍历完成后还需要额外对最后的一行或者一列进行单独遍历,而循环的每一圈,我们只需要对

---->

↑     | 

|     |

|      |

|      ↓

<-----            

这四个for循环,同时保证每一次都是左闭右闭区间

代码一


class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        int m = matrix.size();
        if (m == 0)    return {};
        vector<int> res;
        int n = matrix[0].size();
        int _min = min(m, n);
        int times = 0;
        int quan;
        if (_min % 2 != 0) {
            quan = (_min - 1) / 2;
        }
        else quan = _min / 2;
        while (times<quan) {
            //1.times行,[times,n-times-2]列
            for (int temp = times; temp <= n - times - 2; ++temp) { res.push_back(matrix[times][temp]); }
            //2.[times,m-2-times]行,n-time-1列
            for (int temp = times; temp <= m - 2 - times; ++temp) { res.push_back(matrix[temp][n-times-1]); }
            //3.m-1-times行,[n-1-times,times+1]列
            for (int temp = n - 1 - times; temp >= times + 1; --temp) { res.push_back(matrix[m - 1 - times][temp]); }
            //4.[m-1-times,times+1]行,times列
            for (int temp = m - 1 - times; temp >= times + 1; --temp) { res.push_back(matrix[temp][times]); }
            ++times;
        }
        if (_min % 2 != 0) {        //如果是奇数圈
            if (_min == m) {    //最后行为奇数
                for (int temp = times; temp <= n - 1 - times; ++temp) {
                    res.push_back(matrix[times][temp]);
                }
            }
            else {              //最后列为奇数
                for (int temp = times; temp <= m - 1 - times; ++temp) {
                    res.push_back(matrix[temp][times]);
                }
            }
        }
        return res;
    }
};

思路二 

 核心思想:我们模拟压栈和弹栈的过程,弹栈的过程和poped数组进行比较,如果正确,那么辅助栈最后应该为NULL,同时index应该等于边界.

压入弹出栈的顺序,我们需要模拟压入栈的这个过程,怎么模拟呢?每一次压入的时候,辅助栈的top就和poped数组下标为index的元素进行比较,如果相同,辅助栈就pop,同时index下标右移,对于辅助栈当前状态,有两种选择,一种选择,弹出栈内部分元素,同时和poped[index]比较,如果相同就移动index同时弹出辅助栈top (),直到辅助栈为空或者辅助栈的top()!=poped[index].

代码二

#include<stack>
#include<vector>
using namespace std;

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        stack<int> acce;
        int index = 0;
        for (int i = 0; i < pushed.size();++i) {
            acce.push(pushed[i]);
            if (acce.top() == popped[index]) {
                while (!acce.empty()&&acce.top() == popped[index]) {
                    acce.pop();
                    ++index;
                }
            }
        }
        /*for (int i = index; i < popped.size(); ++i) {
            if (acce.top() == popped[i]) {
                acce.pop();
            }
        }*/
        if (acce.empty())    return true;
        else return false;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shallow_Carl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值