You are given a 0-indexed m x n binary matrix grid. You can move from a cell (row, col) to any of the cells (row + 1, col) or (row, col + 1) that has the value 1. The matrix is disconnected if there is no path from (0, 0) to (m – 1, n – 1).
You can flip the value of at most one (possibly none) cell. You cannot flip the cells (0, 0) and (m – 1, n – 1).
Return true if it is possible to make the matrix disconnect or false otherwise.
Note that flipping a cell changes its value from 0 to 1 or from 1 to 0.
你給予一個 index 為 0 的 m x n 二進制矩陣網格。 你可以從格子 (row, col) 移動到值為 1 的任何 (row + 1, cow) 或 (row, col + 1) 的格子。 如果沒有從 (0, 0) 到 (m - 1, n - 1) 的路徑,則矩陣將連結斷掉。 你最多可翻轉一個格子的值(也可能一個都不翻)。你不能翻轉 (0, 0) 和 (m - 1, n - 1) 的格子。 如果可以連結斷了,則回傳 true,否則回傳 false。 注意,翻轉格子會將其值從 0 變更為 1,或由 1 變更為 0。
Example 1:
Input: grid = [[1,1,1],[1,0,0],[1,1,1]] Output: true Explanation: We can change the cell shown in the diagram above. There is no path from (0, 0) to (2, 2) in the resulting grid.
Example 2:
Input: grid = [[1,1,1],[1,0,1],[1,1,1]] Output: false Explanation: It is not possible to change at most one cell such that there is not path from (0, 0) to (2, 2).
Solution:
這題的意思是,如果這個矩陣一開始可以從左上走到右下,
那可不可以翻轉最多 1 個格字的數值(也可以不翻),讓這個左上到右下的連結斷掉。
我們先從左上走到右下,同時確認格子上方或左方能不能連接(是否為 1),如果不能則設為0。
我們在從右下走到左上,同時確認格子下方或右方能不能連接(是否為 1),如果不能則設為0。
最後我們沿著對角線確認 vis1, vis2 哪些格子兩邊都能連接,如果某條對角線可到達的格子為 <= 1,
則連接的路線可以斷開,回傳 true,否則回傳 false。
Code 1: BigO(m ^ 2 + m * n)
function isPossibleToCutPath(grid: number[][]): boolean { const m: number = grid.length; const n: number = grid[0].length; const vis1: number[][] = Array.from({length:m}, (_, i) => [...grid[i]]); const vis2: number[][] = Array.from({length: m}, (_, i) => [...grid[i]]); for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { if (i === 0 && j === 0) continue; const fromTop: boolean = i !== 0 && vis1[i - 1][j] === 1; const fromLeft: boolean = j !== 0 && vis1[i][j - 1] === 1; if (!fromTop && ! fromLeft) { vis1[i][j] = 0; } } } for (let i = m - 1; i >= 0; i--) { for (let j = n - 1; j >= 0; j--) { if (i === m - 1 && j === n - 1) continue; const fromBottom: boolean = i !== m - 1 && vis2[i + 1][j] === 1; const fromRight: boolean = j !== n - 1 && vis2[i][j + 1] === 1; if (!fromBottom && !fromRight) { vis2[i][j] = 0; } } } for (let x = 1; x < m + n - 2; x++) { let count: number = 0; for (let y = 0; y < m; y++) { const s = x - y; if (s < 0 || s >= n) continue; if (vis1[y][s] === 1 && vis2[y][s] === 1) count++; } if (count <= 1) return true; } return false; };
FlowChart:
Example 1
Input: grid = [[1,1,1],[1,0,0],[1,1,1]] vis1 [ -> [ 1, 1, 1 ], -> [ 1, 0, 0 ], -> [ 1, 1, 1 ] ] vis2 [ [ 1, 0, 0 ], <- [ 1, 0, 0 ], <- [ 1, 1, 1 ] <- ] mapping [ [ [ [ [ 1, 0, 0 ], [ 1, ●, 0] [ 1, 0, ●] [ 1, 0, 0] [ 1, 0, 0 ], -> [ ●, 0, 0] -> [ 1, ●, 0] -> [ 1, 0, ●] [ 1, 1, 1 ] [ 1, 1, 1] [ ●, 1, 1] [ 1, ●, 1] ] [ [ [ count = 0 count = 1 return true;
Example 2
Input: grid = [[1,1,1],[1,0,1],[1,1,1]] vis1 [ -> [ 1, 1, 1 ], -> [ 1, 0, 1 ], -> [ 1, 1, 1 ] ] vis2 [ [ 1, 1, 1 ], <- [ 1, 0, 1 ], <- [ 1, 1, 1 ] <- ] mapping [ [ [ [ [ 1, 1, 1 ], [ 1, ●, 0] [ 1, 0, ●] [ 1, 0, 0] [ 1, 0, 1 ], -> [ ●, 0, 0] -> [ 1, ●, 0] -> [ 1, 0, ●] [ 1, 1, 1 ] [ 1, 1, 1] [ ●, 1, 1] [ 1, ●, 1] ] [ [ [ count = 1 count = 1 count = 1 count = 2 count = 1 count = 2 count = 2 return false;