边工作边刷题:70天一遍leetcode: day 81-1

Alien Dictionary

要点:topological sort,bfs

  • 只有前后两个word之间构成联系,一个word里的c是没有关系的
  • 只要得到两个word第一个不同char之间的partial order即可。topological sort就是把partial order变为total order

错误点:

  • ''.join(res)*(set(res)==chars)的含义:string*int,如果int是0那么实际返回的是''
  • defaultdict usage: umap[k] and umap[k]=0是不同的,前者不会强制set为0
  • don’t be too smart to compact everything: 比如可以开始建graph和indegree来保证所有char in (list comprehension can extend to dict comprehension)
  • zip新用法:相邻两两比较:构建pair: 注意zip不是等长的list,只返回有效部分。
  • 在构建graph的时候indegree[v]+=1对v已经在集合里的情况会重复++
# There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.

# For example,
# Given the following words in dictionary,

# [
#   "wrt",
#   "wrf",
#   "er",
#   "ett",
#   "rftt"
# ]
# The correct order is: "wertf".

# Note:
# You may assume all letters are in lowercase.
# If the order is invalid, return an empty string.
# There may be multiple valid order of letters, return any one of them is fine.
# Hide Company Tags Google Airbnb Facebook Twitter Snapchat Pocket Gems
# Hide Tags Graph Topological Sort
# Hide Similar Problems (M) Course Schedule II

class Solution(object):
    def alienOrder(self, words):
        """
        :type words: List[str]
        :rtype: str
        """
        chars = set([c for word in words for c in word]) # error: inner loop at the end
        graph, indegree = {c:set() for c in chars}, {c:0 for c in chars}

        for pair in zip(words, words[1:]): # note: zip if not even, ignore redundant
            w1,w2 = pair[0],pair[1]
            i = 0
            while i<len(w1) and i<len(w2):
                if w1[i]!=w2[i]:
                    graph[w1[i]].add(w2[i])
                    # indegree[w2[i]]+=1 # error case: w2[i] already in set, wrongly count twice
                    break
                i+=1
        
        for u in graph:
            for v in graph[u]:
                indegree[v]+=1
        
        #print graph, indegree
        q = [c for c in indegree if indegree[c]==0]
        res = []
        while q:
            next = []
            for c in q:
                res.append(c)
                for n in graph[c]:
                    indegree[n]-=1
                    if indegree[n]==0:
                        next.append(n)
            q = next
        
        return ''.join(res)*(set(res)==chars) # error: don't forget cycle

sol = Solution()
assert sol.alienOrder(["ab","adc"])=="acbd"
assert sol.alienOrder(["wrt","wrf","er","ett","rftt"])=="wertf"
assert sol.alienOrder(["za","zb","ca","cb"])=="azbc"
assert sol.alienOrder(["ri","xz","qxf","jhsguaw","dztqrbwbm","dhdqfb","jdv","fcgfsilnb","ooby"])==""

posted @ 2016-07-27 19:26  absolute100  阅读(189)  评论(0编辑  收藏  举报