我理解下面的代码来查找字符串是否是同构的。该代码分别使用两个哈希t_dict
和def isIsomorphic(s, t):
s_dict = {}
t_dict = {}
for i in range(len(s)):
if s[i] in s_dict.keys() and s_dict[s[i]] != t[i]:
return False
if t[i] in t_dict.keys() and t_dict[t[i]] != s[i]:
return False
s_dict[s[i]] = t[i]
t_dict[t[i]] = s[i]
return True
。我假设字符串长度相同。
s_dict()
现在,如果我修改上面的代码,只使用一个哈希def isIsomorphic(s, t):
s_dict = {}
for i in range(len(s)):
if s[i] in s_dict.keys() and s_dict[s[i]] != t[i]:
return False
s_dict[s[i]] = t[i]
return True
,那么它也会给我有限的测试用例提供所需的结果。修改后的代码如下:
new ProductView
上述修改后的代码失败的测试用例是什么?我对同构字符串的理解是错误的吗?
答案 0 :(得分:5)
一个简单的例子,您的代码不适用于s =' ab',t =' aa'。
基本上你必须有两种同构的方式。您的代码只检查了可以从s修改t,但不是相反。
答案 1 :(得分:2)
这看起来很有趣。只是为了踢,这是我使用itertools.groupby
from itertools import groupby
from collections import defaultdict
def get_idx_count(word):
"""Turns a word into a series of tuples (idx, consecutive_chars)
"aabbccaa" -> [[(0, 2), (3, 2)], [(1, 2)], [(2, 2)]]
"""
lst = defaultdict(list)
for idx, (grp, val) in enumerate(groupby(word)):
lst[grp].append((idx, sum(1 for _ in val)))
return sorted(list(lst.values()))
def is_isomorphic(a, b):
return get_idx_count(a) == get_idx_count(b)
is_isomorphic('aabbcc', 'bbddcc') # True
is_isomorphic('aabbaa', 'bbddcc') # False
而不是建立列表,我觉得我可以做更多的事情:
from itertools import groupby
from collections import defaultdict
def is_isomorphic(a, b):
a_idxs, b_idxs = defaultdict(set), defaultdict(set)
for idx, ((a_grp, a_vals), (b_grp, b_vals)) in enumerate(zip(groupby(a), groupby(b))):
if sum(1 for _ in a_vals) != sum(1 for _ in b_vals):
return False
# ensure sequence is of same length
if a_grp in a_idxs and b_idxs[b_grp] != a_idxs[a_grp] or\
b_grp in b_idxs and a_idxs[a_grp] != b_idxs[b_grp]:
return False
# ensure previous occurrences are matching groups
a_idxs[a_grp].add(idx)
b_idxs[b_grp].add(idx)
# save indexes for future checks
return True
但我没有机会对此进行测试。但是,它确实有可能提前退出,而不是必须构建所有列表并在最后进行比较。它也跳过了几组不需要的排序,除了我们从dicts中拉出来,所以很好。非常确定list.sort
比保存到collections.OrderedDict
要快。我想。
答案 2 :(得分:0)
这是Python中同构字符串问题的解决方案:
解决方案1(最快的解决方案):
def isometric_strings_translate(str1: str, str2: str) -> bool:
trans = str.maketrans(str1, str2)
return str1.translate(trans) == str2
解决方案2(使用设置):
def isometric_strings_set(str1: str, str2: str) -> bool:
return len(set(zip(str1, str2))) == len(set(str1))
解决方案3(使用字典):
def isometric_strings_dict(str1: str, str2: str) -> bool:
map = {}
for s1, s2 in zip(str1, str2):
if map.setdefault(s1, s2) != s2:
return False
return True
答案 3 :(得分:0)
在没有地图或词典的情况下进行思考可以帮助您理解:
def isIso(x,y):
if len(x) != len(y):
return False
for i in range(len(x)):
count = 0
if x.count(x[i]) != y.count(y[i]):
return False
return True