Leetcode #329 Longest Increasing Path in a Matrix – 陪你刷題

本篇文章要來探討 Leetcode #329 Longest Increasing Path in a Matrix

方法 1 DFS + Memorization

單純的做 DFS 也可以找出最長 path ,但是時間複雜度太大。

觀察每次的 DFS ,會發現有許多重複子問題,以下圖的 matrix[0][1] 為例 ,他可能由左手邊跟下方的點走到 (0,1) 位置,代表從這個點出發作 DFS 會發生兩次,

想避免做重複子問題,如同動態規劃做法,將曾經做過的結果 cache 起來,避免重複計算,因此這題採取 DFS 加上 cache 來解決。

有一點值得一提,通常不會用 DFS 搭配 cache 作法,因為你很可能會走到重覆的路徑而導致形成 cycle ,但因為這題有了 increasing order 的限制,因而避開形成 cycle 的可能性。

class Solution {
public:
    int dir_row[4] = {-1, 0, 1, 0};
    int dir_col[4] = {0, -1, 0, 1};

    int longestIncreasingPath(vector<vector<int>>& matrix) {
        int max_len = 1;
        vector<vector<int>> cache (matrix.size(), vector<int>(matrix[0].size(), 0));
        for (int i=0; i<matrix.size(); i++) {
            for (int j=0; j<matrix[0].size(); j++) {
                max_len = std::max(max_len, dfs_helper(matrix, cache, i, j));
            }
        }
        return max_len;
    }

    int dfs_helper (vector<vector<int>>& matrix, vector<vector<int>>& result,
                    int row, int col) {
        if (result[row][col] != 0) {
            return result[row][col];
        }
        for (int i=0; i<4; i++) {

            int next_row = row + dir_row[i];
            int next_col = col + dir_col[i];

            if (next_row >=0 && next_row < matrix.size()
               && next_col >= 0 && next_col < matrix[0].size()
               && matrix[next_row][next_col] > matrix[row][col]) 
            {
                result[row][col] = 
                    std::max (dfs_helper(matrix, result, next_row, next_col)+1, result[row][col]);
            }
        }
        if (result[row][col] == 0) result[row][col] = 1;
        return result[row][col];
    }
};

Time Complexity O(mn)
Space Complextiy O(mn)

方法 2 Topological sort

根據題目的要求,將 Increasing path 連結起來,就可以將 matrix 看成是一個 DAG (有向連通圖) ,畫成圖後,對於要找出最長的 path 就更加容易理解了。

在一個 DAG 中,想要梳理出這樣的前後關係,可以想到 Topological sort ,在 topological sort 過程中,每輪都會選擇 inDgree 為 0 的點,做為新一輪的延伸,因此我們可以說總共做了幾輪,也就代表找到最長 path 的長度。 你可以透過上圖幫助你理解,並且搭配本站之前的文章 Topological Sort – 陪你刷題來複習 topological sort 。

class Solution {
public:
    int dir_row[4] = {-1, 0, 1, 0};
    int dir_col[4] = {0, 1, 0, -1};
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        int row = matrix.size();
        int col = matrix[0].size();
        vector<vector<int>> indegree(row, vector<int>(col, 0));

        for(int i=0; i<row; i++) {
            for (int j=0; j<col; j++) {
                for (int k=0; k<4; k++) {
                    int neighbor_row = i+dir_row[k];
                    int neighbor_col = j+dir_col[k];
                    if (neighbor_row >= 0 && neighbor_row < row
                       && neighbor_col >=0 && neighbor_col <col
                       && matrix[neighbor_row][neighbor_col] < matrix[i][j]){
                        indegree[i][j]++;
                    }
                }

            }
        }

        queue<pair<int, int>> qu;
        for (int i=0; i<row; i++) {
            for (int j=0; j<col; j++) {
                if (indegree[i][j] == 0) {
                    qu.push({i,j});
                }
            }
        }

        int len = 0;
        while (!qu.empty()) {
            len++;
            int size = qu.size();
            for (int i=0; i<size; i++) {
                pair<int, int> node = qu.front();
                qu.pop();
                // Check all its neighbor node
                for (int d=0; d<4; d++) {
                    int neighbor_row = node.first + dir_row[d];
                    int neighbor_col = node.second + dir_col[d];

                    if (neighbor_row >= 0 && neighbor_row < row
                       && neighbor_col >=0 && neighbor_col <col
                       && matrix[neighbor_row][neighbor_col] 
                        > matrix[node.first][node.second]){
                        indegree[neighbor_row][neighbor_col]--;
                        if (indegree[neighbor_row][neighbor_col] == 0) {
                            qu.push({neighbor_row, neighbor_col});
                        }
                    }
                }
            }
        }
        return len;
    }
};

Time Complexity O(mn)

Space Complexity O(mn)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *