6767- 当状态为 $010$ 型时:下一行可能的状态为:$101$, $102$, $121$, $201$, $202$。这 $5$ 个状态可归纳为 $3$ 个 $010$ 型,$2$ 个 $012$ 型。
6868- 当状态为 $012$ 型时:下一行可能的状态为:$101$, $120$, $121$, $201$。这 $4$ 个状态可归纳为 $2$ 个 $010$ 型,$2$ 个 $012$ 型。
6969
70- 综上所述,可以得到:$newf0 = 3 * f0 + 2 * f1$, $newf1 = 2 * f0 + 2 * f1$。
70+ 综上所述,可以得到:$newf0 = 3 \times f0 + 2 \times f1$, $newf1 = 2 \times f0 + 2 \times f1$。
7171
72- 时间复杂度 $O(n)$。
72+ 时间复杂度 $O(n)$,其中 $n$ 是网格的行数。空间复杂度 $O(1)$。
73+
74+ ** 方法二:状态压缩 + 动态规划**
75+
76+ 我们注意到,网格只有 $3$ 列,那么一行中最多有 $3^3=27$ 种不同的涂色方案。
77+
78+ 因此,我们定义 $f[ i] [ j ] $ 表示前 $i$ 行中,第 $i$ 行的涂色状态为 $j$ 的方案数。状态 $f[ i] [ j ] $ 由 $f[ i - 1] [ k ] $ 转移而来,其中 $k$ 是第 $i - 1$ 行的涂色状态,且 $k$ 和 $j$ 满足不同颜色相邻的要求。即:
79+
80+ $$
81+ f[i][j] = \sum_{k \in \text{valid}(j)} f[i - 1][k]
82+ $$
83+
84+ 其中 $\text{valid}(j)$ 表示状态 $j$ 的所有合法前驱状态。
85+
86+ 最终的答案即为 $f[ n] [ j ] $ 的总和,其中 $j$ 是任意合法的状态。
87+
88+ 我们注意到,$f[ i] [ j ] $ 只和 $f[ i - 1] [ k ] $ 有关,因此我们可以使用滚动数组优化空间复杂度。
89+
90+ 时间复杂度 $O((m + n) \times 3^{2m})$,空间复杂度 $O(3^m)$。其中 $n$ 和 $m$ 分别是网格的行数和列数。
7391
7492<!-- tabs:start -->
7593
@@ -89,6 +107,44 @@ class Solution:
89107 return (f0 + f1) % mod
90108```
91109
110+ ``` python
111+ class Solution :
112+ def numOfWays (self , n : int ) -> int :
113+ def f1 (x : int ) -> bool :
114+ last = - 1
115+ for _ in range (3 ):
116+ if x % 3 == last:
117+ return False
118+ last = x % 3
119+ x //= 3
120+ return True
121+
122+ def f2 (x : int , y : int ) -> bool :
123+ for _ in range (3 ):
124+ if x % 3 == y % 3 :
125+ return False
126+ x //= 3
127+ y //= 3
128+ return True
129+
130+ mod = 10 ** 9 + 7
131+ m = 27
132+ valid = {i for i in range (m) if f1(i)}
133+ d = defaultdict(list )
134+ for i in valid:
135+ for j in valid:
136+ if f2(i, j):
137+ d[i].append(j)
138+ f = [int (i in valid) for i in range (m)]
139+ for _ in range (n - 1 ):
140+ g = [0 ] * m
141+ for i in valid:
142+ for j in d[i]:
143+ g[j] = (g[j] + f[i]) % mod
144+ f = g
145+ return sum (f) % mod
146+ ```
147+
92148### ** Java**
93149
94150<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -109,6 +165,68 @@ class Solution {
109165}
110166```
111167
168+ ``` java
169+ class Solution {
170+ public int numOfWays (int n ) {
171+ final int mod = (int ) 1e9 + 7 ;
172+ int m = 27 ;
173+ Set<Integer > valid = new HashSet<> ();
174+ int [] f = new int [m];
175+ for (int i = 0 ; i < m; ++ i) {
176+ if (f1(i)) {
177+ valid. add(i);
178+ f[i] = 1 ;
179+ }
180+ }
181+ Map<Integer , List<Integer > > d = new HashMap<> ();
182+ for (int i : valid) {
183+ for (int j : valid) {
184+ if (f2(i, j)) {
185+ d. computeIfAbsent(i, k - > new ArrayList<> ()). add(j);
186+ }
187+ }
188+ }
189+ for (int k = 1 ; k < n; ++ k) {
190+ int [] g = new int [m];
191+ for (int i : valid) {
192+ for (int j : d. getOrDefault(i, List . of())) {
193+ g[j] = (g[j] + f[i]) % mod;
194+ }
195+ }
196+ f = g;
197+ }
198+ int ans = 0 ;
199+ for (int x : f) {
200+ ans = (ans + x) % mod;
201+ }
202+ return ans;
203+ }
204+
205+ private boolean f1 (int x ) {
206+ int last = - 1 ;
207+ for (int i = 0 ; i < 3 ; ++ i) {
208+ if (x % 3 == last) {
209+ return false ;
210+ }
211+ last = x % 3 ;
212+ x /= 3 ;
213+ }
214+ return true ;
215+ }
216+
217+ private boolean f2 (int x , int y ) {
218+ for (int i = 0 ; i < 3 ; ++ i) {
219+ if (x % 3 == y % 3 ) {
220+ return false ;
221+ }
222+ x /= 3 ;
223+ y /= 3 ;
224+ }
225+ return true ;
226+ }
227+ }
228+ ```
229+
112230### ** C++**
113231
114232``` cpp
@@ -130,6 +248,69 @@ public:
130248};
131249```
132250
251+ ```cpp
252+ class Solution {
253+ public:
254+ int numOfWays(int n) {
255+ int m = 27;
256+
257+ auto f1 = [&](int x) {
258+ int last = -1;
259+ for (int i = 0; i < 3; ++i) {
260+ if (x % 3 == last) {
261+ return false;
262+ }
263+ last = x % 3;
264+ x /= 3;
265+ }
266+ return true;
267+ };
268+ auto f2 = [&](int x, int y) {
269+ for (int i = 0; i < 3; ++i) {
270+ if (x % 3 == y % 3) {
271+ return false;
272+ }
273+ x /= 3;
274+ y /= 3;
275+ }
276+ return true;
277+ };
278+
279+ const int mod = 1e9 + 7;
280+ unordered_set<int> valid;
281+ vector<int> f(m);
282+ for (int i = 0; i < m; ++i) {
283+ if (f1(i)) {
284+ valid.insert(i);
285+ f[i] = 1;
286+ }
287+ }
288+ unordered_map<int, vector<int>> d;
289+ for (int i : valid) {
290+ for (int j : valid) {
291+ if (f2(i, j)) {
292+ d[i].push_back(j);
293+ }
294+ }
295+ }
296+ for (int k = 1; k < n; ++k) {
297+ vector<int> g(m);
298+ for (int i : valid) {
299+ for (int j : d[i]) {
300+ g[j] = (g[j] + f[i]) % mod;
301+ }
302+ }
303+ f = move(g);
304+ }
305+ int ans = 0;
306+ for (int x : f) {
307+ ans = (ans + x) % mod;
308+ }
309+ return ans;
310+ }
311+ };
312+ ```
313+
133314### ** Go**
134315
135316``` go
@@ -146,6 +327,140 @@ func numOfWays(n int) int {
146327}
147328```
148329
330+ ``` go
331+ func numOfWays (n int ) (ans int ) {
332+ f1 := func (x int ) bool {
333+ last := -1
334+ for i := 0 ; i < 3 ; i++ {
335+ if x%3 == last {
336+ return false
337+ }
338+ last = x % 3
339+ x /= 3
340+ }
341+ return true
342+ }
343+ f2 := func (x, y int ) bool {
344+ for i := 0 ; i < 3 ; i++ {
345+ if x%3 == y%3 {
346+ return false
347+ }
348+ x /= 3
349+ y /= 3
350+ }
351+ return true
352+ }
353+ m := 27
354+ valid := map [int ]bool {}
355+ f := make ([]int , m)
356+ for i := 0 ; i < m; i++ {
357+ if f1 (i) {
358+ valid[i] = true
359+ f[i] = 1
360+ }
361+ }
362+ d := map [int ][]int {}
363+ for i := range valid {
364+ for j := range valid {
365+ if f2 (i, j) {
366+ d[i] = append (d[i], j)
367+ }
368+ }
369+ }
370+ const mod int = 1e9 + 7
371+ for k := 1 ; k < n; k++ {
372+ g := make ([]int , m)
373+ for i := range valid {
374+ for _ , j := range d[i] {
375+ g[i] = (g[i] + f[j]) % mod
376+ }
377+ }
378+ f = g
379+ }
380+ for _ , x := range f {
381+ ans = (ans + x) % mod
382+ }
383+ return
384+ }
385+ ```
386+
387+ ### ** TypeScript**
388+
389+ ``` ts
390+ function numOfWays(n : number ): number {
391+ const mod: number = 10 ** 9 + 7 ;
392+ let f0: number = 6 ;
393+ let f1: number = 6 ;
394+
395+ for (let i = 1 ; i < n ; i ++ ) {
396+ const g0: number = (3 * f0 + 2 * f1 ) % mod ;
397+ const g1: number = (2 * f0 + 2 * f1 ) % mod ;
398+ f0 = g0 ;
399+ f1 = g1 ;
400+ }
401+
402+ return (f0 + f1 ) % mod ;
403+ }
404+ ```
405+
406+ ``` ts
407+ function numOfWays(n : number ): number {
408+ const f1 = (x : number ): boolean => {
409+ let last = - 1 ;
410+ for (let i = 0 ; i < 3 ; ++ i ) {
411+ if (x % 3 === last ) {
412+ return false ;
413+ }
414+ last = x % 3 ;
415+ x = Math .floor (x / 3 );
416+ }
417+ return true ;
418+ };
419+ const f2 = (x : number , y : number ): boolean => {
420+ for (let i = 0 ; i < 3 ; ++ i ) {
421+ if (x % 3 === y % 3 ) {
422+ return false ;
423+ }
424+ x = Math .floor (x / 3 );
425+ y = Math .floor (y / 3 );
426+ }
427+ return true ;
428+ };
429+ const m = 27 ;
430+ const valid = new Set <number >();
431+ const f: number [] = Array (m ).fill (0 );
432+ for (let i = 0 ; i < m ; ++ i ) {
433+ if (f1 (i )) {
434+ valid .add (i );
435+ f [i ] = 1 ;
436+ }
437+ }
438+ const d: Map <number , number []> = new Map ();
439+ for (const i of valid ) {
440+ for (const j of valid ) {
441+ if (f2 (i , j )) {
442+ d .set (i , (d .get (i ) || []).concat (j ));
443+ }
444+ }
445+ }
446+ const mod = 10 ** 9 + 7 ;
447+ for (let k = 1 ; k < n ; ++ k ) {
448+ const g: number [] = Array (m ).fill (0 );
449+ for (const i of valid ) {
450+ for (const j of d .get (i ) || []) {
451+ g [i ] = (g [i ] + f [j ]) % mod ;
452+ }
453+ }
454+ f .splice (0 , f .length , ... g );
455+ }
456+ let ans = 0 ;
457+ for (const x of f ) {
458+ ans = (ans + x ) % mod ;
459+ }
460+ return ans ;
461+ }
462+ ```
463+
149464### ** ...**
150465
151466```
0 commit comments