# 289. Game of Life ### Idea 題目要求將生存遊戲 boards 的格點置換為**下一個狀態**<br/> 先不考慮空間複雜度<br/> 最直覺的解法是 1. 創建一個儲存下一個狀態的二維陣列 results 2. 遍歷每個格點把下一個狀態存取到 results (**要小心處理訪問陣列的上下界**) 3. 再遍歷一次將 boards 的格點取代為 results 的格點 時間複雜度為 O( m _ n )<br/> 空間複雜度為 O( m _ n ) ```javascript function gameOfLife(board) { const m = board.length, n = board[0].length, results = Array.from(Array(m), (_) => Array(n)) for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { results[i][j] = setStatus(board, i, j, m, n) } } for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { board[i][j] = results[i][j] } } } function setStatus(board, x, y, m, n) { let liveCount = 0 for (let i = Math.max(0, x - 1); i <= Math.min(m - 1, x + 1); i++) { for (let j = Math.max(0, y - 1); j <= Math.min(n - 1, y + 1); j++) { if (i !== x || j !== y) liveCount += board[i][j] === 1 } } return Number( board[x][y] === 1 ? liveCount >= 2 && liveCount <= 3 : liveCount === 3 ) } ``` ### Refactor 因為實際狀態本身很單純只有生存或死亡<br/> 可以透過**自定義拓展狀態**來最佳化空間的利用<br/> 我們定義每個格點的假想狀態含有**時間變化的意義**(**變化前 → 變化後**) - status = 1, 生存 → 生存 - status = 2, 死亡 → 生存 - status = 3, 生存 → 死亡 - status = 4, 死亡 → 死亡 有了定義的認知後 想法跟前面的思路大體一致 只需要留意以下兩點 1. 在計算各點的假想狀態時將假想狀態的變化前實際狀態考慮進去 2. 遍歷將全部假想狀態正確轉換回實際狀態 時間複雜度為 O( m \* n )<br/> 空間複雜度為 O( 1 ) ```javascript function gameOfLife(board) { /* status of board definition: 0 = dead before, dead after. 1 = alive before, alive after. 2 = alive before, dead after. 3 = dead before, alive after. */ const m = board.length, n = board[0].length for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { board[i][j] = setStatus(board, i, j, m, n) } } for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { board[i][j] %= 2 } } } function setStatus(board, x, y, m, n) { let liveCount = 0 for (let i = Math.max(0, x - 1); i <= Math.min(m - 1, x + 1); i++) { for (let j = Math.max(0, y - 1); j <= Math.min(n - 1, y + 1); j++) { if (i !== x || j !== y) { if (board[i][j] === 2) liveCount += 1 else if (board[i][j] === 3) liveCount += 0 else liveCount += board[i][j] } } } if (board[x][y] === 1 && (liveCount < 2 || liveCount > 3)) return 2 else if (board[x][y] === 0 && liveCount === 3) return 3 else return board[x][y] } ``` ###### tags: `Leetcode` `JavaScript`