剑指offer-20.环形打印二维数组

0 题目

1 分析

首先,将一个圆圈,看作是一次循环,那么第一次循环其实坐标为0,0

当打印完以后,还能在打印的时候,起始坐标为1,1,往后依次为2,2

因此可以使用一个变量来表示起始坐标,start

每当循环依次,那么数组上下左右四个边界都-1。表示已经打印过了

当start大于总的列数/2+1,或是大于总的行数/2+1的时候,表示不能打印了

比如有5列,7行。start=1的时候可以打印,3的时候也可以,但是4的时候就不行了。因为该列已经被打印过了。

同时可以有start和rows和cols,计算上下左右四个打印边界(可以打印到的)。

然后左到右,直接start小于等于右边界即可

上到下,start+1小于等于下边界。

右到左,start+1应该小于等于下边界

下到上,start应该大于下边界-1

vector<int> printMatrix(vector<vector<int>> matrix)
{
    vector<int> res;
    int rows = matrix.size();
    int cols = matrix[0].size();

    int start = 0; // start是每次开始打印时候,xy的坐标,x=y

    while (rows > start * 2 && cols > start * 2)
    {
        int i = 0;

        // 下面两个值,是本次打印的右边界和下边界.可以到达的边界
        int endX = cols - start - 1;
        int endY = rows - start - 1;

        // 左->右,只要 start <= 右边界,就可以打印
        for (i = start; i <= endX; i++)
        {
            res.push_back(matrix[start][i]);
        }

        // 上->下,因为左->右最后打印的那个数,也可以看作是,上->下的第一个数
        // 而这个数已经打印过一次了,所以就跳过这个数。因此是start+1
        for (i = start + 1; i <= endY; i++)
        {
            res.push_back(matrix[i][endX]);
        }

        // 右->左,此时需要判断,是否只有一层,如果只有一层,那么在 左->右 已经打印过一次了
        // 因此 start 必须要大于 endY
        if (start < endY)
        {
            // 从 endx-1 是因为,从上到下的时候,打印了一个
            for (i = endX - 1; i >= start; i--)
            {
                res.push_back(matrix[endY][i]);
            }
        }

        // 下->上,也需要满足上下有多层,左右也有多层。
        // start < endX 保证了,左右是有空间的
        if (start < endX && start < endY - 1)
        {
            // 从  endY - 1 开始,是应为 在从右到左的时候已经打印了它的第一个树
            for (i = endY - 1; i > start; i--)
            {
                res.push_back(matrix[i][start]);
            }
        }

        // 依次循环后,yx的值,要递增,因此start++
        start++;
    }
    return res;
}

    

原文地址:https://www.cnblogs.com/perfy576/p/8607769.html