5.11打卡:剑指 offer两题:顺时针打印矩阵/包含min函数的栈

题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
解题思路1:顺时针打印就是按圈数循环打印,一圈包含两行或者两列,在打印的时候会出现某一圈中只包含一行,要判断从左向右打印和从右向左打印的时候是否会出现重复打印,同样只包含一列时,要判断从上向下打印和从下向上打印的时候是否会出现重复打印的情况

思路2:从外到内,一层层打印。难点在于怎么找到标记点,以及防止重复遍历。

怎么找到标记点?对于每一层来说,设左上角的元素坐标为 (i, j),那么右上角的元素坐标为 (i, n - j - 1),右下角的元素坐标是 (m - i - 1 ,n - j - 1),左下角的元素坐标是 (m - i - 1, j)。找到标记点后,就是对行/列进行+/-的过程。

怎么防止重复遍历?找到四个坐标点后,每一层的遍历可以拆分成 4 个部分。

class Solution {
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        
        //解法1:
        vector<int> res; //定义一维数组
        int m = matrix.size(), n = matrix[0].size(); //定义行为m,列为n
        vector<vector<bool>> st(m,vector<bool>(n,false)); //定义一个二维bool型数组,判定是否数组访问过
        int dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0}; //定义上左下右
        int x = 0, y = 0 ,d = 0; //从(0,0)开始遍历,d = 0表示先从右边开始
        for (int i = 0; i < n * m; i ++) { //访问n*m次
            res.push_back(matrix[x][y]); //将访问的数保存至res一维数组
            st[x][y] = true; //将访问的数定义为false
            int a = x + dx[d], b= y + dy[d];
            if (a < 0 || a >= m || b < 0 || b >= n || st[a][b] ) {
                d = (d + 1) % 4;
                a = x + dx[d], b = y + dy[d];
            }
            x = a, y = b;
        }
        return res;
        /*解法2:
        vector<int>res;
        res.clear();
        int row=matrix.size();//行数
        int collor=matrix[0].size();//列数
        //计算打印的圈数
        int circle=((row<collor?row:collor)-1)/2+1;//圈数
        for(int i=0;i<circle;i++){
            //从左向右打印
            for(int j=i;j<collor-i;j++)
                res.push_back(matrix[i][j]);         
            //从上往下的每一列数据
            for(int k=i+1;k<row-i;k++)
                res.push_back(matrix[k][collor-1-i]);
            //判断是否会重复打印(从右向左的每行数据)
            for(int m=collor-i-2;(m>=i)&&(row-i-1!=i);m--)
                res.push_back(matrix[row-i-1][m]);
            //判断是否会重复打印(从下往上的每一列数据)
            for(int n=row-i-2;(n>i)&&(collor-i-1!=i);n--)
                res.push_back(matrix[n][i]);}
        return res;*/
    }
};

包含min函数的栈

题目描述

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。

注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。

思路:定义两个栈,栈1实现基本功能,栈2保存当前栈状态的最小值
压栈:压栈时若压入值小于栈2的栈顶,将改值压入栈2
出栈:出栈时若栈顶值等于栈2栈顶,栈2也随之出栈
当前栈的最小值即为栈2栈顶值

class Solution {
public:
    stack<int> stk, mm;
    void push(int value) {
        stk.push(value);
        if(mm.empty() || value < mm.top())
            mm.push(value);
    }
    void pop() {
        if(!stk.empty()){
            if(mm.top()==stk.top())
                mm.pop();
            stk.pop();
        }
    }
    int top() {
        if(stk.empty()) return 0;
        return stk.top();
    }
    int min() {
        if(stk.empty()) return 0;
        return mm.top();
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值