【leetcode】756. Pyramid Transition Matrix

题目如下:

We are stacking blocks to form a pyramid. Each block has a color which is a one letter string, like `'Z'`.

For every block of color `C` we place not in the bottom row, we are placing it on top of a left block of color `A` and right block of color `B`. We are allowed to place the block there only if `(A, B, C)` is an allowed triple.

We start with a bottom row of bottom, represented as a single string. We also start with a list of allowed triples allowed. Each allowed triple is represented as a string of length 3.

Return true if we can build the pyramid all the way to the top, otherwise false.

Example 1:

Input: bottom = "XYZ", allowed = ["XYD", "YZE", "DEA", "FFF"]
Output: true
Explanation:
We can stack the pyramid like this:
    A
   / \
  D   E
 / \ / \
X   Y   Z

This works because ('X', 'Y', 'D'), ('Y', 'Z', 'E'), and ('D', 'E', 'A') are allowed triples.

 

Example 2:

Input: bottom = "XXYX", allowed = ["XXX", "XXY", "XYX", "XYY", "YXZ"]
Output: false
Explanation:
We can't stack the pyramid to the top.
Note that there could be allowed triples (A, B, C) and (A, B, D) with C != D.

 

Note:

  1. bottom will be a string with length in range [2, 8].
  2. allowed will have length in range [0, 200].
  3. Letters in all strings will be chosen from the set {'A', 'B', 'C', 'D', 'E', 'F', 'G'}.

解题思路:我的方法是采用DFS,对于判断是否的题目,用DFS的效率要高于BFS。题目中有一点好像没有说明,就是allowed里面的同一个元素可以用多次。遍历allowed,先找出前两个字符与bottom前两个字符相同的元素;然后bottom去掉第一位,再去allowed中找出前两个字符与bottom前两个字符相同的元素,循环直至bottom长度变成1为止;接下来令bottom等于第一轮中找到的所有的元素的最后一个字符拼接组成的新的字符串,重复第一轮的操作。同时每找到一个可以组成bottom的元素,用一个变量used记录个数,直到userd =  len(bottom) * (len(bottom) -1 )/2 表示可以组成如题目要求的bottom。为什么?因为要组成三角形所需的元素个数正好等于 (1+2+3....+最底部bottom的长度)。

代码如下:

class Solution(object):
    def pyramidTransition(self, bottom, allowed):
        """
        :type bottom: str
        :type allowed: List[str]
        :rtype: bool
        """
        queue = []
        dic = {}
        for i in allowed:
            if bottom[:2] == i[:2]:
                queue.append((bottom[1:],i[-1],1))
            if i[:2] not in dic:
                dic[i[:2]] = [i]
            else:
                dic[i[:2]].append(i)

        while len(queue) > 0:
            #print len(queue)
            bot,path,used = queue.pop(0)
            #print used
            if used == len(bottom) * (len(bottom) -1 )/2:
                return True
            elif len(bot) < 2:
                queue.insert(0,(path,'',used+1))
            else:
                if bot[:2] in dic:
                    for i in dic[bot[:2]]:
                        queue.insert(0,(bot[1:], path + i[-1], used + 1))
        return False

 

posted @ 2019-02-27 19:36  seyjs  阅读(368)  评论(0编辑  收藏  举报