《劍指offer》 面試題29. 順時針打印矩陣

題目描述

輸入一個矩陣,按照從外向裏以順時針的順序依次打印出每一個數字。

示例 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]

限制:
0 <= matrix.length <= 100
0 <= matrix[i].length <= 100

按路徑模擬

仔細研究下矩陣,會發現就順時針按固定的四個方向。因此抓住這一點就能解決

可以模擬打印矩陣的路徑。初始位置是矩陣的左上角,初始方向是向右,當路徑超出界限或者進入之前訪問過的位置時,則順時針旋轉,進入下一個方向。

判斷路徑是否進入之前訪問過的位置需要使用一個與輸入矩陣大小相同的輔助矩陣 visited,其中的每個元素表示該位置是否被訪問過。當一個元素被訪問時,將 visited 中的對應位置的元素設爲已訪問。

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if (matrix.size() == 0 || matrix[0].size() == 0) {
            return {};
        }
        int len_x = matrix.size();
        int len_y = matrix[0].size();
        vector<int> res(len_x*len_y);
        vector<vector<bool>> vis(len_x, vector(len_y, false));
        int next[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        int duration = 0;
        int x = 0;
        int y = 0;
        res[0] = matrix[x][y];
        vis[x][y] = true;
        for(int i = 1; i < len_x*len_y; i++){
            int tx = x + next[duration][0];
            int ty = y + next[duration][1];
            
            if(tx < 0 || tx >= len_x || ty < 0 || ty >= len_y || vis[tx][ty]){
                duration = (duration+1)%4;
                tx = x + next[duration][0];
                ty = y + next[duration][1];
            }

            vis[tx][ty] = true;
            res[i] = matrix[tx][ty];
            x = tx;
            y = ty;
        }
        return res;
    }
};

按層模擬

將矩陣看成若干層,首先打印最外層的元素,其次打印次外層的元素,直到打印最內層的元素。

對於每層,從左上方開始以順時針的順序遍歷所有元素。假設當前層的左上角位於(top,left),右下角位於 (bottom,right),按照如下順序遍歷當前層的元素。

  1. 從左到右遍歷上側元素,依次爲(top,left) 到 (top,right)。
  2. 從上到下遍歷右側元素,依次爲 (top+1,right) 到(bottom,right)。
  3. 如果left<right 且 top<bottom,則從右到左遍歷下側元素,依次爲 (bottom,right−1) 到 (bottom,left+1),以及從下到上遍歷左側元素,依次爲(bottom,left) 到 (top+1,left)。

遍歷完當前層的元素之後,將 left 和op 分別增加 1,將 right 和 bottom 分別減少 1,進入下一層繼續遍歷,直到遍歷完所有元素爲止。
在這裏插入圖片描述

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if (matrix.empty() || matrix[0].empty())	return {};
        int top   = 0;
        int bot   = matrix.size() - 1;
        int left  = 0;
        int right = matrix[0].size() - 1;
        vector<int> result(matrix.size() * matrix[0].size());
        int index = 0;
        while (top <= bot && left <= right)
        {
            for (int i = left; i <= right; ++i){
                result[index++] = matrix[top][i];
            }
            ++top;
            if (top > bot)	break;
            for (int i = top; i <= bot; ++i){
                result[index++]= matrix[i][right];
            }
            --right;
            if (left > right)	break;
            for (int i = right; i >= left; --i){
                result[index++]= matrix[bot][i];
            }
            --bot;
            if (top > bot)	break;
            for (int i = bot; i >= top; --i){
                result[index++] = matrix[i][left];
            }
            ++left;
        }
        return result;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章