第55周 ARTS 2019 11 03

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’
解决方案
这种条纹的窗帘,这样鸟儿就不会因为玻璃而里面的倒影而撞楼了。

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

发布了139 篇原创文章 · 获赞 13 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章