通过“破解编码面试”的方式工作,然后出现一个实践问题
给出2个字符串,编写一个方法来确定一个是否是另一个的排列。
作者的python解决方案如下:
def check_permutation(str1, str2):
if len(str1) != len(str2):
return False
counter = Counter()
for c in str1:
counter[c] += 1
for c in str2:
if counter[c] == 0:
return False
counter[c] -= 1
return True
声称自己属于O(N)时间。
我的解决方法如下:
def perm(str1,str2):
if(len(str1) != len(str2)):
return False
for c in str1:
if c not in Str2:
return False
return True
我相信这也是O(N)。这是真的?哪种算法有利?作者的数据类型似乎不必要。
最后,这个算法是O(NlogN)吗?
def perm(str1,str2):
return sorted(str1)==sorted(str2)
答案 0 :(得分:3)
首先,作者的解决方案是Counter(str1) == Counter(str2)
的优化版本(它更快地返回False
并创建Counter
的单个实例)。
确实是O(n)
,因为哈希表(Counter
)访问是O(1)
。
接下来,您的解决方案是二次(O(n^2)
),因为每个in
是O(n)
-它必须遍历整个字符串。
带重复的字符串也是错误的。
第三,sorted(str1) == sorted(str2)
实际上是线性方程(O(n*log(n))
)
因此比原始的线性解还差。
但是请注意,对于 small 字符串,常量可能会使
差异和线性方程(sorted
)解可能是
比线性(Counter
)更快。
最后,请注意,Python通常是使用解释器实现的,因此实际性能可能取决于您使用的是C还是Python中实现的功能。例如,如果Counter
是用C实现的,那么即使从算法上来说作者的解决方案更好,{>
答案 1 :(得分:0)
对于第一个代码,使用collection.Counter
而不是循环可能很容易:
def check_permutation(str1, str2):
if len(str1) != len(str2):
return False
return Counter(str1) == Counter(str2)
又是O(n)
。最后一个算法是sorted
,使用O(nlogn)
进行排序和使用。
您的算法不正确,因为您在另一个字符串中找到了一个字符而又不关心该字符的重复次数。如果为真,则为O(n^2)
。
因此,一般来讲,第一种算法具有最佳的时间复杂度并且易于实现。