生活随笔
收集整理的這篇文章主要介紹了
【LeetCode】4月2日打卡-Day18-矩阵操作
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題1 生命游戲
描述
根據 百度百科 ,生命游戲,簡稱為生命,是英國數學家約翰·何頓·康威在 1970 年發明的細胞自動機。
給定一個包含 m × n 個格子的面板,每一個格子都可以看成是一個細胞。每個細胞都具有一個初始狀態:1 即為活細胞(live),或 0 即為死細胞(dead)。每個細胞與其八個相鄰位置(水平,垂直,對角線)的細胞都遵循以下四條生存定律:
如果活細胞周圍八個位置的活細胞數少于兩個,則該位置活細胞死亡;
如果活細胞周圍八個位置有兩個或三個活細胞,則該位置活細胞仍然存活;
如果活細胞周圍八個位置有超過三個活細胞,則該位置活細胞死亡;
如果死細胞周圍正好有三個活細胞,則該位置死細胞復活;
根據當前狀態,寫一個函數來計算面板上所有細胞的下一個(一次更新后的)狀態。下一個狀態是通過將上述規則同時應用于當前狀態下的每個細胞所形成的,其中細胞的出生和死亡是同時發生的
示例:
輸入:
[
[0,1,0],
[0,0,1],
[1,1,1],
[0,0,0]
]
輸出:
[
[0,0,0],
[1,0,1],
[0,1,1],
[0,1,0]
]
進階:
你可以使用原地算法解決本題嗎?請注意,面板上所有格子需要同時被更新:你不能先更新某些格子,然后使用它們的更新后的值再更新其他格子。
本題中,我們使用二維數組來表示面板。原則上,面板是無限的,但當活細胞侵占了面板邊界時會造成問題。你將如何解決這些問題?
題解
這個題和之前的地圖題很像,實現思路沒有問題,但是實現的時候有問題。我第一個的問題出在把if判斷寫成了while導致超時,第二個的問題出在忘了要同步更新這個要求,各自必須同時更新,所以需要保留原始的格子的值。
法1:拷貝矩陣: 因為需要再創建一個二維矩陣保存原始數據所以內存消耗較大
執行用時 :1 ms, 在所有 Java 提交中擊敗了37.80%的用戶
內存消耗 :38.2 MB, 在所有 Java 提交中擊敗了5.71%的用戶
class Solution {public void gameOfLife(int[][] board
) {int[] neighbors
= {1,-1,0};int[][] copyBoard
= new int[board
.length
][board
[0].length
];for(int i
= 0; i
< board
.length
; i
++){for(int j
= 0; j
< board
[0].length
; j
++){copyBoard
[i
][j
] = board
[i
][j
];}}for(int i
= 0; i
< board
.length
; i
++){for(int j
= 0; j
< board
[0].length
; j
++){int alive
= 0;for(int a
= 0; a
< 3; a
++){for(int b
= 0; b
< 3; b
++){if(neighbors
[a
]!=0 || neighbors
[b
] != 0){int r
= i
+neighbors
[a
];int c
= j
+neighbors
[b
];if(r
>=0&&r
<board
.length
&&c
>=0&&c
<board
[0].length
&©Board
[r
][c
]==1){alive
++;}}}}if ((copyBoard
[i
][j
]==1)&&(alive
<2||alive
>3)) {board
[i
][j
] = 0;}if (copyBoard
[i
][j
] == 0 && alive
== 3) {board
[i
][j
] = 1;}}}}
}
法2 定義復合狀態法
空間復雜度為O(1) 時間復雜度同上O(mn)
根據數組的細胞狀態計算新一輪的細胞狀態,這里會用到能同時代表過去狀態和現在狀態的復合狀態。
具體的計算規則如下所示:
規則 1:如果活細胞周圍八個位置的活細胞數少于兩個,則該位置活細胞死亡。這時候,將細胞值改為 -1,代表這個細胞過去是活的現在死了;
規則 2:如果活細胞周圍八個位置有兩個或三個活細胞,則該位置活細胞仍然存活。這時候不改變細胞的值,仍為 1;
規則 3:如果活細胞周圍八個位置有超過三個活細胞,則該位置活細胞死亡。這時候,將細胞的值改為 -1,代表這個細胞過去是活的現在死了。可以看到,因為規則 1 和規則 3 下細胞的起始終止狀態是一致的,因此它們的復合狀態也一致;
規則 4:如果死細胞周圍正好有三個活細胞,則該位置死細胞復活。這時候,將細胞的值改為 2,代表這個細胞過去是死的現在活了。
class Solution {public void gameOfLife(int[][] board
) {int[] neighbors
= {0, 1, -1};int rows
= board
.length
;int cols
= board
[0].length
;for (int row
= 0; row
< rows
; row
++) {for (int col
= 0; col
< cols
; col
++) {int liveNeighbors
= 0;for (int i
= 0; i
< 3; i
++) {for (int j
= 0; j
< 3; j
++) {if (!(neighbors
[i
] == 0 && neighbors
[j
] == 0)) {int r
= (row
+ neighbors
[i
]);int c
= (col
+ neighbors
[j
]);if ((r
< rows
&& r
>= 0) && (c
< cols
&& c
>= 0) && (Math
.abs(board
[r
][c
]) == 1)) {liveNeighbors
+= 1;}}}}if ((board
[row
][col
] == 1) && (liveNeighbors
< 2 || liveNeighbors
> 3)) {board
[row
][col
] = -1;}if (board
[row
][col
] == 0 && liveNeighbors
== 3) {board
[row
][col
] = 2;}}}for (int row
= 0; row
< rows
; row
++) {for (int col
= 0; col
< cols
; col
++) {if (board
[row
][col
] > 0) {board
[row
][col
] = 1;} else {board
[row
][col
] = 0;}}}}
}
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的【LeetCode】4月2日打卡-Day18-矩阵操作的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。