劍指 Offer 29-順時針列印矩陣c++

小pig飼養員發表於2020-12-02

題目描述

在這裡插入圖片描述

解法一 深度優先進化版法

一開始的思路是用深度優先做出來,只要指定順時針方向,用深度優先走一遍,如果沒有路可以走直接break即可。
然後就覺得既然拐點處可以特殊處理,按照原本深度優先的思想,每次越界時改變方向即可,省去深度優先嚐試其他方向的次數。

class Solution {
private:
    int next[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if (matrix.size() == 0 || matrix[0].size() == 0) {
            return {};
        }
        int rows = matrix.size();
        int columns = matrix[0].size();
        vector<vector<bool>> book(rows, vector<bool>(columns));
        int count = rows * columns;
        vector<int> order(count);

        int x = 0, y = 0;
        int tx,ty;
        int dir = 0;
        for (int i = 0; i < count; i++) {
            order[i] = matrix[x][y];
            book[x][y] = true;
            tx = x + next[dir][0];
            ty = y + next[dir][1];
            if (tx < 0 || tx >= rows || ty < 0 || ty >= columns || book[tx][ty]) dir = (dir + 1) % 4;
            x += next[dir][0];
            y += next[dir][1];
        }
        return order;
    }
};

在這裡插入圖片描述
矩陣列數為m,行數為n
時間複雜度O(mn),空間複雜度O(mn);

解法二

一開始思考的過程中,有想過通過前面每次走完一個方向來減少另一個方向的可走次數,然後順時針四個方向重複,直到一個方向減少到不能走為止。
但是想到深度優先覺得自己已經行了 懶就不沒再去實現了。
然後看到住在精選的大佬就是這樣做的…
大佬的題解

class Solution:
    def spiralOrder(self, matrix:[[int]]) -> [int]:
        if not matrix: return []
        l, r, t, b, res = 0, len(matrix[0]) - 1, 0, len(matrix) - 1, []
        while True:
            for i in range(l, r + 1): res.append(matrix[t][i]) # left to right
            t += 1
            if t > b: break
            for i in range(t, b + 1): res.append(matrix[i][r]) # top to bottom
            r -= 1
            if l > r: break
            for i in range(r, l - 1, -1): res.append(matrix[b][i]) # right to left
            b -= 1
            if t > b: break
            for i in range(b, t - 1, -1): res.append(matrix[i][l]) # bottom to top
            l += 1
            if l > r: break
        return res

時間複雜度O(m*n),空間複雜度O(1)

相關文章