我们模拟方块可以处于的状态。每个状态都是一个二进制数,如果第 k 类型的方块是可能的,则设置第 k 位。然后,我们创建一个转换映射 T[state1][state2] -> state。它接受左状态和右状态并输出所有可能的父状态。
最后,应用这些转换非常简单。但是,这种方法不正确,因为转换不是独立的。例如,如果我们在一行 A, {B or C}, A,并且 allowed 中的元组是 (A, B, D), (C, A, D)。那么无论选择 {B or C},我们都不能创建金字塔的下一行。
[solution1-Python]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution(object): defpyramidTransition(self, bottom, allowed): T = [[0] * (1 << 7) for _ in xrange(1 << 7)] for triple in allowed: u, v, w = (1 << (ord(x) - ord('A')) for x in triple) for b1 in xrange(1 << 7): if u & b1: for b2 in xrange(1 << 7): if v & b2: T[b1][b2] |= w
state = [1 << (ord(x) - ord('A')) for x in bottom] whilelen(state) > 1: for i in xrange(len(state) - 1): state[i] = T[state[i]][state[i+1]] state.pop() returnbool(state[0])
classSolution(object): defpyramidTransition(self, bottom, allowed): T = collections.defaultdict(set) for u, v, w in allowed: T[u, v].add(w)
#Comments can be used to cache intermediate results #seen = set() defsolve(A): iflen(A) == 1: returnTrue #if A in seen: return False #seen.add(A) returnany(solve(cand) for cand in build(A, []))
defbuild(A, ans, i = 0): if i + 1 == len(A): yield"".join(ans) else: for w in T[A[i], A[i+1]]: ans.append(w) for result in build(A, ans, i+1): yield result ans.pop()
seen = newHashSet(); intN= bottom.length(); int[][] A = newint[N][N]; intt=0; for (char c: bottom.toCharArray()) A[N-1][t++] = c - 'A'; return solve(A, 0, N-1, 0); }
//A[i] - the ith row of the pyramid //R - integer representing the current row of the pyramid //N - length of current row we are calculating //i - index of how far in the current row we are calculating //Returns true iff pyramid can be built publicbooleansolve(int[][] A, long R, int N, int i) { if (N == 1 && i == 1) { // If successfully placed entire pyramid returntrue; } elseif (i == N) { if (seen.contains(R)) returnfalse; // If we've already tried this row, give up seen.add(R); // Add row to cache return solve(A, 0, N-1, 0); // Calculate next row } else { // w's jth bit is true iff block #j could be // a parent of A[N][i] and A[N][i+1] intw= T[A[N][i]][A[N][i+1]]; // for each set bit in w... for (intb=0; b < 7; ++b) if (((w >> b) & 1) != 0) { A[N-1][i] = b; //set parent to be equal to block #b //If rest of pyramid can be built, return true //R represents current row, now with ith bit set to b+1 // in base 8. if (solve(A, R * 8 + (b+1), N, i+1)) returntrue; } returnfalse; } } }
复杂度分析
时间复杂度:O(\mathcal{A}^{N}),其中 N 指的是 bottom 的长度,\mathcal{A 指的是字母的大小。