题目链接
https://leetcode.com/problems/number-of-ways-to-paint-n-3-grid
题目描述
给定大小为n*3的网格图,每个格子只能涂上红、黄、绿三种颜色之一,并且确保任意两个相邻方格颜色不同。给定网格图的行数n,返回给网格图涂色的方案数。由于方案数会比较大,返回方案数对10^9+7取余的结果即可。
示例
输入:n=1
输出:12
解题思路·动态规划
对于n*3大小的网格图,我们一层一层地涂色。 第一行保证左右相邻方格颜色不同,包含两种颜色组成形式:
(1)两端方格颜色相同,且和中间方格颜色不同,可记为aba;
(2)三个方格颜色都不同,可记为abc。
用1、2、3三个数字分别代表红、黄、绿三种颜色,那么aba形式有6种颜色组合:121、131、212、232、323、313;同样的,abc形式有6种颜色组合:123、132、213、231、321、312。
如果第一层为aba形式的颜色组合,如121,那么第二层会对应5种颜色组合,分别为232、212、313、213、312,即3个属于aba形式的颜色组合+2个属于abc形式的颜色组合。
如果第一层为abc形式的颜色组合,如123,那么第二层会对应4种颜色组合,分别为312、231、232、212,即2个属于aba形式的颜色组合+2个属于abc形式的颜色组合。
因此可以定义为第n层的颜色组合中符合abc形式的颜色组合,定义
为第n层的颜色组合中符合aba形式的颜色组合。可以得到下面的递推式:
最后返回即可。
Python实现
class Solution:
def numOfWays(self, n: int) -> int:
aba,abc,num_mod = 6,6,10**9+7 #初始化第一层不同形式的组合数
for i in range(2,n+1):
#先执行等式右边的表达式计算(按从左到右的顺序执行等式右边的代码)赋值操作也是按从左到右的顺序执行:
aba,abc = 3 * aba + 2 * abc,2 * aba + 2 * abc
return (aba + abc) % num_mod
时间复杂度与空间复杂度
由于只遍历一次,时间复杂度为O(n)。空间复杂度为O(1)。
扩展
Python可以存储任意大的整数(可参照《Python源码剖析》中的第2章),因此可以在最后对(aba+abc)取余。但是在c++和Java中需要将aba和abc初始化为long类型,并且需要在for循环体里对abc和aba进行取余。