Given a pattern and a dictionary, print out all the strings that match the pattern. A character in the pattern is mapped uniquely to a character in the dictionary. e.g.:
- ('abc', ['cdf', 'too', 'hgfdt', 'paa']) -> output = ['cdf']
- ('acc', ['cdf', 'too', 'hgfdt', 'paa']) -> output = ['too', 'paa']
给出一个字符串pattern和一个字典,求字典里面所有和这个pattern匹配的字符串,所谓匹配就是说pattern和该字符串可以不重复地一一映射。
1. 询问
和字符串相关的问题,总是可以问一些问题的:字符是不是只有小写字母?是不是ASCII码字符?因为假如只有小写字母或者ASCII字符,很多时候哈希表都可以认为是O(1)空间的。这里假设可以是任意字符。
输出顺序有没有要求?假设没有要求。
2. 分析
基本思路
这道题的基本思路,就是一个个比较,然后挑出符合要求的。关键就在于比较判断的过程。
于是问题转化为,给出两个字符串s和t,能不能实现一一映射?
思路也很简单,就是建立哈希表按顺序一个个映射,如果发现之前已经映射过了,那么就不符合。因为映射有两个方向,
因此从s到t和从t到s都需要判断。例如s='abc',t='too',到c的时候,因为已经建立了b和o的映射,所以不符合条件。再比如s='too',t='abc',这时建立了o和b的映射,也不符合条件。
因此,需要两个字典,分别记录s到t的映射和t到s的映射,然后每次进来新的字符对,查一下两个方向的映射是否存在,只要存在一个就不符合条件。
综上,假设pattern长度为L,时间复杂度是O(nL),空间复杂度O(L),因为可以反复使用同一片空间。
细节
首先很显然的一点就是,长度不一样的无需再比较。
然后,用Python的话,zip函数在这里可以派上用场。事实上,把s和t放一起zip之后,假如是满足条件的,应该有len(set(zip(s,t))) == len(set(s)) == len(set(t))。因为假如有一侧的两个字符都映射到另一侧的同一个字符,那么也就是说另一侧有两个相同的字符,取set之后长度会不相同。当然有一个可能性就是两边都这样,比如aabc和htoo,因此还要把zip加进来。
这种解法,代码看上去更加少,就具体效率而言不见得更好。但是就面试的环境而言,第二种解法更满足面试的需求,代码少,水平高。
3. 代码
class Solution:
def patternMatch(self, s, d):
if s is None or not d:
return []
ret = []
for t in d:
if len(s) == len(t) and \
len(set(zip(s, t))) == len(set(s)) == len(set(t)):
ret.append(t)
return ret
4. 总结
难度Easy。