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’
这种条纹的窗帘,这样鸟儿就不会因为玻璃而里面的倒影而撞楼了。
其实从我们创造了各种各样的科技来帮助我们解决各种各样的问题,也在给自然界中那些动物们创造各种各样的问题。
高楼大厦解决我们的工作空间,生存空间的问题,把土地资源的利用率强行提升,也在给原来的那些鸟儿们制造了麻烦。
正如乔帮主所倡导的那样,我们要同时兼具“科技与人文”,科技是自己,我想人文可以是自然。
我们可以找到一个和自然和平共处的方式的,但是需要我么一个个不断的自我改变。
宫崎骏在《幽灵公主》中,曾表达了他自己的一种愿望,希望有一天,人们可以和自然和解,可以看到自然的强大,然后不要试图去破坏他们。那是宫崎骏的自己的一种愿望,他自己也说他还没早到最佳答案。
当然也许没有最佳答案,我们只不过在找答案的过程中,慢慢地前进着一步又一步。