• [LeetCode in Python] 5383 (H) number of ways to paint n x 3 grid 给 N x 3 网格图涂色的方案数


    题目:

    https://leetcode-cn.com/problems/number-of-ways-to-paint-n-x-3-grid/

    你有一个 n x 3的网格图 grid,你需要用 红,黄,绿三种颜色之一给每一个格子上色,且确保相邻格子颜色不同(也就是有相同水平边或者垂直边的格子颜色不同)。
    给你网格图的行数 n。
    请你返回给grid涂色的方案数。由于答案可能会非常大,请你返回答案对10^9 + 7取余的结果。

    示例 1:

    输入:n = 1
    输出:12
    解释:总共有 12 种可行的方法:

    示例 2:

    输入:n = 2
    输出:54

    示例 3:

    输入:n = 3
    输出:246

    示例 4:

    输入:n = 7
    输出:106494

    示例 5:

    输入:n = 5000
    输出:30228214

    提示:

    n == grid.length
    grid[i].length == 3
    1 <= n <= 5000

    解题思路

    • 使用数学方法当然是最销魂的,咱还是用简单粗暴的方法吧。
    • 显而易见,只要确定了相邻两行的转换关系,剩下的就是迭代了。
    • 手写第一行的模式,只有12个,多乎哉?不多也。
    • 然后穷举遍历,得到这12个模式对应的全部可能的下一行模式,存为next字典备用。
    • 将第一行的模式存为prev字典,key是模式,value初始化为1,表示第一行每种模式都只有1个。
    • 然后就是从第2行开始遍历到最后一行。
    • 在每一行的开始,先存一个字典curr,存储每种模式出现的次数。
    • 然后重点来了!
    • 遍历prev的key,从next[key]中取得全部可能的模式,更新curr[next[key]]。
    • 注意这里更新的时候,需要每次累加prev[key]。
    • 在每行结束的时候,将curr的内容存入prev。
    • 程序最后将prev的value求和再取模,完事儿。

    代码

    class Solution:
        def numOfWays(self, n: int) -> int:
            pattern = [
              'RGB', 'RBG', 'RGR',
              'RBR', 'GBR', 'GRB',
              'GRG', 'GBG', 'BRG',
              'BGR', 'BRB', 'BGB'
            ]
    
            # - construct transfer dict
            # - to handle adjacent rows
            next = {}
            for p1 in pattern:
              next[p1] = []
              for p2 in pattern:
                is_ok = True
                for i in range(3):
                  if p1[i] == p2[i]:
                    is_ok = False
                    break
                if is_ok:
                  next[p1].append(p2)
            
            # - first row
            prev = {p:1 for p in pattern}
            
            # - from second row
            for i in range(n-1):
                # - d is temp dict for current row
                curr = {p:0 for p in pattern}
                
                # - accumulate
                for k,v in prev.items():
                    for x in next[k]:
                        curr[x] += v
                
                # - update previous row
                prev = copy.copy(curr)
                
            return sum(prev.values()) % (10**9 + 7)
    
  • 相关阅读:
    Python Day23
    Python Day22
    Python Day21
    Python Day20
    Python Day19
    Python Day18
    Python Day17
    Python Day15
    Appium python unittest pageobject如何实现加载多个case
    Appium python Uiautomator2 多进程问题
  • 原文地址:https://www.cnblogs.com/journeyonmyway/p/12684662.html
Copyright © 2020-2023  润新知