1 class Solution(object): 2 def __init__(self): 3 self.count = 0 4 5 def dfs(self, tiles, used, visited, path): 6 7 if len(path) > 0 and path not in visited: 8 visited.add(path) 9 self.count += 1 10 11 for i in range(len(tiles)): 12 if used[i]: 13 continue 14 used[i] = True 15 self.dfs(tiles, used, visited, path + tiles[i]) 16 used[i] = False 17 18 19 def numTilePossibilities(self, tiles): 20 """ 21 :type tiles: str 22 :rtype: int 23 """ 24 25 visited = set() 26 used = [False] * len(tiles) 27 self.dfs(tiles, used, visited, "") 28 return self.count
回溯法,与全排列使用list不同,这里要去掉同样的字符,因此使用set进行标记。(注意25行visited的定义)
另外一行样式:
1 class Solution: 2 def numTilePossibilities(self, tiles: str) -> int: 3 return sum(len(set(itertools.permutations(tiles, i))) for i in range(1, len(tiles) + 1))
这样的写法很帅,但是可读性差一些,把代码分开来看:
1 import itertools 2 3 class Solution: 4 def numTilePossibilities(self, tiles: str) -> int: 5 sums = 0 6 for i in range(1, len(tiles) + 1): 7 permu = itertools.permutations(tiles, i) 8 s = set(permu) 9 sums += len(s) 10 return sums
使用itertools,生成字符串的排列序列,简单又方便,效率也高。就是其他语言没有这种东西,不具有通用性。
参考:https://leetcode.com/problems/letter-tile-possibilities/discuss/308518/Python-1-liner