劍指offer-20.環形打印二維數組

0 題目

1 分析

首先,將一個圓圈,看做是一次循環,那麼第一次循環其實座標爲0,0數組

當打印完之後,還能在打印的時候,起始座標爲1,1,日後依次爲2,2blog

所以能夠使用一個變量來表示起始座標,startclass

 

每當循環依次,那麼數組上下左右四個邊界都-1。表示已經打印過了變量

當start大於總的列數/2+1,或是大於總的行數/2+1的時候,表示不能打印了循環

好比有5列,7行。start=1的時候能夠打印,3的時候也能夠,可是4的時候就不行了。由於該列已經被打印過了。di

 

同時能夠有start和rows和cols,計算上下左右四個打印邊界(能夠打印到的)。while

而後左到右,直接start小於等於右邊界便可co

上到下,start+1小於等於下邊界。push

右到左,start+1應該小於等於下邊界return

下到上,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;
}
相關文章
相關標籤/搜索