[LeetCode] Game of Life

According to the Wikipedia’s article: “The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970.”

Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article):

1. Any live cell with fewer than two live neighbors dies, as if caused by under-population.
2. Any live cell with two or three live neighbors lives on to the next generation.
3. Any live cell with more than three live neighbors dies, as if by over-population..
4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.

Write a function to compute the next state (after one update) of the board given its current state.

Follow up:

1. Could you solve it in-place? Remember that the board needs to be updated at the same time: You cannot update some cells first and then use their updated values to update other cells.
2. In this question, we represent the board using a 2D array. In principle, the board is infinite, which would cause problems when the active area encroaches the border of the array. How would you address these problems?

解题思路

题目要求就地解决问题,所以不能计算出结果之后马上更新该位置的值。因此我们考虑用十位个位分别表示下一代的值和当前代的值,计算live成员个数时,我们累加board[i][j] % 10的值,等用十位把所有位置都标记完后统一更新所有位置的值(board[i][j] /= 10)。

实现代码

C++:

// Runtime: 4 ms
class Solution {
public:
    void gameOfLife(vector<vector<int>>& board) {
        for (int i = 0; i < board.size(); i++)
        {
            for (int j = 0; j < board[0].size(); j++)
            {
                int num = numOfLive(board, i, j);
                if (board[i][j] == 1 && (num == 2 || num == 3) ||
                    board[i][j] == 0 && num == 3)
                {
                    board[i][j] += 10;
                }
            }
        }

        for (int i = 0; i < board.size(); i++)
        {
            for (int j = 0; j < board[0].size(); j++)
            {
                board[i][j] /= 10;
            }
        }
    }
private:
    int numOfLive(vector<vector<int>> board, int m, int n)
    {
        int res = 0;
        for (int i = m - 1; i <= m + 1; i++)
        {
            for (int j = n - 1; j <= n + 1; j++)
            {
                if (i < 0 || j < 0 || i > board.size() - 1 ||
                    j > board[0].size() - 1 || (i == m && j == n))
                {
                    continue;
                }
                res += board[i][j] % 10;
            }
        }

        return res;
    }
};

Java:

// Runtime: 1 ms
public class Solution {
    public void gameOfLife(int[][] board) {
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                int num = numOfLive(board, i, j);
                if (board[i][j] == 1 && (num == 2 || num == 3) ||
                        board[i][j] == 0 && num == 3) {
                    board[i][j] += 10;
                }
            }
        }

        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                board[i][j] /= 10;
            }
        }
    }

    private int numOfLive(int[][] board, int m, int n) {
        int res = 0;
        for (int i = m - 1; i <= m + 1; i++) {
            for (int j = n - 1; j <= n + 1; j++) {
                if (i < 0 || j < 0 || i > board.length - 1 ||
                        j > board[0].length - 1 || (i == m && j == n)) {
                    continue;
                }
                res += board[i][j] % 10;
            }
        }

        return res;
    }
}
时间: 2024-08-30 15:10:03

[LeetCode] Game of Life的相关文章

代码分析-leetcode:Scramble String问题

问题描述 leetcode:Scramble String问题 题目:Given a string s1 we may represent it as a binary tree by partitioning it to two non-empty substrings recursively. Below is one possible representation of s1 = ""great"": great / gr eat / / g r e at /

c++-leetcode Median of Two Sorted Arrays

问题描述 leetcode Median of Two Sorted Arrays class Solution { public: double findMedianSortedArrays(vector& nums1, vector& nums2) { if(nums1.size()==0){ if(nums2.size()%2==0)return ((double)nums2[nums2.size()/2]+nums2[nums2.size()/2-1])/2.0; else ret

[LeetCode]61.Rotate List

[题目] Given a list, rotate the list to the right by k places, where k is non-negative. For example: Given 1->2->3->4->5->NULL and k = 2, return 4->5->1->2->3->NULL. [题意] 给定一个链表,向右旋转k个位置,其中k是非负的. [分析] 先遍历一遍,得出链表长度 len,注意 k 可能大于

[LeetCode]91.Decode Ways

题目 A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' -> 1 'B' -> 2 - 'Z' -> 26 Given an encoded message containing digits, determine the total number of ways to decode it. For example, Given encode

LeetCode总结之二分查找篇

二分查找算法虽然简单,但面试中也比较常见,经常用来在有序的数列查找某个特定的位置.在LeetCode用到此算法的主要题目有: Search Insert Position Search for a Range Sqrt(x) Search a 2D Matrix Search in Rotated Sorted Array Search in Rotated Sorted Array II 这类题目基本可以分为如下四种题型: 1. Search Insert Position和Search fo

Restore IP Addresses:LeetCode

原题链接: http://oj.leetcode.com/problems/restore-ip-addresses/ 这道题的解法非常接近于NP问题,也是采用递归的解法.基本思路就是取出一个合法的数字,作为IP地址的一项,然后递归处理剩下的项.可以想象出一颗树,每个结点有三个可能的分支(因为范围是0-255,所以可以由一位两位或者三位组成).并且这里树的层数不会超过四层,因为IP地址由四段组成,到了之后我们就没必要再递归下去,可以结束了.这里除了上述的结束条件外,另一个就是字符串读完了.可以看

Simplify Path:LeetCode

原题链接: http://oj.leetcode.com/problems/simplify-path/ 这道题目是Linux内核中比较常见的一个操作,就是对一个输入的文件路径进行简化.思路比较明确,就是维护一个栈,对于每一个块(以'/'作为分界)进行分析,如果遇到'../'则表示要上一层,那么就是进行出栈操作,如果遇到'./'则是停留当前,直接跳过,其他文件路径则直接进栈即可.最后根据栈中的内容转换成路径即可(这里是把栈转成数组,然后依次添加).时间上不会超过两次扫描(一次是进栈得到简化路径,

4Sum:LeetCode

这道题要求跟3Sum差不多,只是需求扩展到四个的数字的和了.我们还是可以按照3Sum中的解法,只是在外面套一层循环,相当于求n次3Sum.我们知道3Sum的时间复杂度是O(n^2),所以如果这样解的总时间复杂度是O(n^3).代码如下: public ArrayList<ArrayList<Integer>> fourSum(int[] num, int target) { ArrayList<ArrayList<Integer>> res = new Ar

Distinct Subsequences -- LeetCode

原题链接: http://oj.leetcode.com/problems/distinct-subsequences/ 这道题应该很容易感觉到是动态规划的题目.还是老套路,先考虑我们要维护什么量.这里我们维护res[i][j],对应的值是S的前i个字符和T的前j个字符有多少个可行的序列(注意这道题是序列,不是子串,也就是只要字符按照顺序出现即可,不需要连续出现).下面来看看递推式,假设我们现在拥有之前的历史信息,我们怎么在常量操作时间内得到res[i][j].假设S的第i个字符和T的第j个字符

Word Search -- LeetCode

原题链接: http://oj.leetcode.com/problems/word-search/ 这道题很容易感觉出来是图的题目,其实本质上还是做深度优先搜索.基本思路就是从某一个元素出发,往上下左右深度搜索是否有相等于word的字符串.这里注意每次从一个元素出发时要重置访问标记(也就是说虽然单次搜索字符不能重复使用,但是每次从一个新的元素出发,字符还是重新可以用的).深度优先搜索的算法就不再重复解释了,不了解的朋友可以看看wiki - 深度优先搜索.我们知道一次搜索的复杂度是O(E+V),