Algorithm 289. 生命遊戲
Review Become a Master of Java Streams — Part 1: Creating Streams
Tip/Tech 數據庫的索引
Share 機器學習就是個炒作
Algorithm
289. 生命遊戲
https://leetcode-cn.com/problems/game-of-life/
這他的難點就在於,你要原地算法來解決這個問題。
原地算法:你只能用常數的空間複雜度。
這裏的解決之道就是用標記法重新標記,然後再根據標記來找到結果。
這段說明可以讓你更好地理解:
起始 | 終了 | 狀態碼 | 說明 |
---|---|---|---|
0 | 0 | 2 | |
0 | 1 | 3 | 死細胞周圍正好有三個活細胞,則該位置死細胞復活; |
1 | 0 | 4 | 活細胞周圍八個位置的活細胞數少於2個,則該位置活細胞死亡;如果活細胞周圍八個位置有超過3個活細胞,則該位置活細胞死亡; |
1 | 1 | 5 | 活細胞周圍八個位置有兩個或三個活細胞,則該位置活細胞仍然存活; |
class Solution {
public void gameOfLife(int[][] board) {
if (board == null || board.length == 0 || board[0].length == 0){
return;
}
int rowSize = board.length;
int colSize = board[0].length;
for (int i = 0; i < rowSize; ++i) {
for (int j = 0; j < colSize; ++j) {
getTempResult(i, j, rowSize, colSize, board);
}
}
//再根據狀態碼再去得到最後的結果值。
for (int i = 0; i < rowSize; ++i) {
for (int j = 0; j < colSize; ++j) {
if (board[i][j] == 2 || board[i][j] == 4) {
board[i][j] = 0;
}
if (board[i][j] == 3 || board[i][j] == 5) {
board[i][j] = 1;
}
}
}
}
/**
* 起始 終了 狀態碼
* 0 0 2
* 0 1 3 死細胞周圍正好有三個活細胞,則該位置死細胞復活;
* 1 0 4 活細胞周圍八個位置的活細胞數少於2個,則該位置活細胞死亡;如果活細胞周圍八個位置有超過3個活細胞,則該位置活細胞死亡;
* 1 1 5 活細胞周圍八個位置有兩個或三個活細胞,則該位置活細胞仍然存活;
*/
private int getTempResult(int rowIndex, int colIndex, int rowSize, int colSize, int[][] board) {
int top = Math.max(0, rowIndex - 1);
int bottom = Math.min(rowSize - 1, rowIndex + 1);
int left = Math.max(0, colIndex -1);
int right = Math.min(colSize - 1, colIndex + 1);
int count = 0;
for (int i = top; i <= bottom; ++i) {
for (int j = left; j <= right; ++j) {
if (i == rowIndex && j == colIndex) {
continue;
}
if (board[i][j] == 1 || board[i][j] == 4 || board[i][j] == 5 ) {
count++;
}
}
}
if (board[rowIndex][colIndex] == 0) {
if (count == 3) {
board[rowIndex][colIndex] = 3;
} else {
board[rowIndex][colIndex] = 2;
}
} else {
if (count < 2 || count > 3) {
board[rowIndex][colIndex] = 4;
} else if (count == 2 || count == 3) {
board[rowIndex][colIndex] = 5;
}
}
return 0;
}
}
Review
Become a Master of Java Streams, Part 2: Intermediate Operations
https://dzone.com/articles/become-a-master-of-java-streams-part-2-intermediat
本片是上一篇的延續,講的是關於Stream的中間操作(Intermediate Operations)這點很關鍵目前Java的stream主要有這麼幾個操作:
- Filter
過濾操作, - Limit
- Skip
- Distinct
- Sorted
- Sorted With Comparator
Stream<String> lengthOrder = Stream.of("Monkey", "Lion", "Giraffe", "Lemur")
.sorted(Comparator.comparing(String::length));
lengthOrder: [Lion, Lemur, Monkey, Giraffe]
- Map
這個可以最簡單的應用就是吧某個元素給轉換爲別的元素。 - Map to Integer, Double or Long
這個可以吧流的元素全部改變。 - FlatMap
這個不好解釋,我也不懂要怎麼解釋,就是把所有的元素拆了?拆成不能再拆?然後變成一個流?
Tip/Tech
Java容器之LinkedList全解析
https://mp.weixin.qq.com/s/psLuW2G4uJIqDjvwnyYbjg
這是篇很基礎的文章,但是卻很不錯。我之前也寫過關於源碼分析的文章,但是寫的沒有這篇好。
首先代碼幹了什麼事情,類各種依賴,構造圖是哪些。這些都是非常好的樣板。
具體到代碼,LinkedList底層用的是雙向鏈表的思想。
在原來的鏈表的基礎操作的上,要加入相應的判斷是否是第一個點和最後一個點。
以下是文章中提到的,自己實現的部分:
public class LinkedList1<T> {
private Node1<T> first;
private Node1<T> last;
private int size;
/**
* 增加節點,默認是增加在最後的
* @param data
*/
public void add(T data) {
// 先用臨時變量存放last變量
Node1<T> tempLast = last;
// 構造新的點,新的點的前一個點是last,後一個是null
Node1<T> newNode = new Node1(data, tempLast, null);
// 把last引用指向最後一個新的點
last = newNode;
// 判斷之前的last是否爲空,如果爲空,那麼這個原來就是空鏈表。
if (tempLast == null ) {
first = newNode;
} else {
// 不爲空那麼就把最後一個點給安排上
tempLast.next = newNode;
}
size++;
}
/**
* 刪除節點,默認的是遍歷,找到對應的值後刪除
* @param data 根據data來刪除
*/
public boolean remove(Object data) {
if (data == null) {
for (Node1<T> index = first; index != null; index = index.next) {
if (index.data == null) {
unlink(index);
return true;
}
}
} else {
for (Node1<T> index = first; index != last; index = index.next) {
if (data.equals(index.data)) {
unlink(index);
return true;
}
}
}
return false;
}
/**
*
* @param node
*/
public void unlink(Node1<T> node) {
Node1<T> preNode = node.pre;
Node1<T> nextNode = node.next;
// deal preNode.next
// make node.pre = null, to help GC.
if (preNode == null) {
first = node.next;
} else {
preNode.next = nextNode;
node.pre = null;
}
// deal nextNode.pre
// make node.next = null, help GC
if (nextNode == null) {
last = preNode;
} else {
nextNode.pre = preNode;
node.next = null;
}
// help GC
node.data = null;
size--;
}
/**
*
* @param data
* @return
*/
public T get(Object data) {
if (data == null) {
return null;
}
for (Node1<T> cursor = first; cursor != null; cursor = cursor.next) {
if (data.equals(cursor.data)){
return cursor.data;
}
}
return null;
}
public T getByIndex(int index) {
if (index >= size) {
throw new IllegalArgumentException("index is out of bound.");
}
if (index > (size >> 1)) {
Node1<T> cursor = last;
for (int i = size - 1; i >= 0; --i) {
if (i == index) {
return cursor.data;
}
cursor = cursor.pre;
}
} else {
Node1<T> cursor = first;
for (int i = 0; i < size; i++) {
if (i == index) {
return cursor.data;
}
cursor = cursor.next;
}
}
return null;
}
static class Node1<T> {
private T data;
private Node1<T> pre;
private Node1<T> next;
public Node1(T data, Node1<T> pre, Node1<T> next) {
this.data = data;
this.pre = pre;
this.next = next;
}
}
}
Share
‘Zen curtain’ saves birds from hitting glass windows at University of Queensland
https://www.abc.net.au/news/2019-10-28/the-curtain-saving-birds-from-hitting-glass-windows/11638774
很多鳥類飛到城市的後會因爲高樓層的玻璃的而喪失勢力,就會撞到玻璃,前段時間按也有相似的新聞,不過這個文章的主角是鸚鵡,但是那篇新聞的主角是遷徙的鳥。
文章中的這個PhD student Adam Hines
爲了幫助這些不想自殺卻被迫自殺的鳥,解決方案就是 ‘zen curtain’
這種條紋的窗簾,這樣鳥兒就不會因爲玻璃而裏面的倒影而撞樓了。
其實從我們創造了各種各樣的科技來幫助我們解決各種各樣的問題,也在給自然界中那些動物們創造各種各樣的問題。
高樓大廈解決我們的工作空間,生存空間的問題,把土地資源的利用率強行提升,也在給原來的那些鳥兒們製造了麻煩。
正如喬幫主所倡導的那樣,我們要同時兼具“科技與人文”,科技是自己,我想人文可以是自然。
我們可以找到一個和自然和平共處的方式的,但是需要我麼一個個不斷的自我改變。
宮崎駿在《幽靈公主》中,曾表達了他自己的一種願望,希望有一天,人們可以和自然和解,可以看到自然的強大,然後不要試圖去破壞他們。那是宮崎駿的自己的一種願望,他自己也說他還沒早到最佳答案。
當然也許沒有最佳答案,我們只不過在找答案的過程中,慢慢地前進着一步又一步。