第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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章