No.0005-CareerCup

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.:

  1. ('abc', ['cdf', 'too', 'hgfdt', 'paa']) -> output = ['cdf']
  2. ('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。

你可能感兴趣的:(No.0005-CareerCup)