剑指offer JZ-19

题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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

输入

复制
[[1,2],[3,4]]

返回值

复制
[1,2,4,3]

思路

1.

在遍历矩阵时一共有四种方向,按顺序分别为:右、下、左、上,分别编号为【0,1,2,3】,很容易看出方向的转换满足:next_dir = (now_dir + 1)%4

此时我们只需要判断何时改变方向即可。

class Solution {
public:
    int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
    int len1,len2;
    vector<int> printMatrix(vector<vector<int> > matrix) {
        len1 = matrix.size();
        len2 = matrix[0].size();
        int sum = len1*len2,op = 0;
        int x = 0, y = 0;
        vector<vector<bool> > book;
        for(int i=0;i<len1;i++)
        {
            vector<bool> temp;
            for(int j=0;j<len2;j++)
            {
                temp.push_back(true);
            }
            book.push_back(temp);
        }
        vector<int> ans;
        ans.push_back(matrix[0][0]);
        book[x][y] = false;
        sum--;
        while(sum)
        {
            if(Check(x,y,op,book))
            {
                sum--;
                x += dir[op][0];
                y += dir[op][1];
            }
            else
            {
                op = (op+1)%4;
                sum--;
                x += dir[op][0];
                y += dir[op][1];
            }
            ans.push_back(matrix[x][y]);
            book[x][y] = false;
        }
        return ans;
    }
    bool Check(int x,int y,int op,const vector<vector<bool> > &book)
    {
        int nx = x + dir[op][0];
        int ny = y + dir[op][1];
        if(nx>=len1 || ny>=len2 || nx<0 || ny<0 || book[nx][ny]==false)
            return false;
        return true;
    }
};
View Code

 2.

思路1需要额外维护一个标记数组,实际上这个标记数组不是必须的

我们可以通过左上角坐标和右下角左边来唯一确定一个矩阵,按顺序打印当前矩阵的四边后,将左上角坐标和右下角坐标沿对角线方向移动得到新的矩阵。重复上述过程直到结束即可。

 
原文地址:https://www.cnblogs.com/alan-W/p/14275084.html