给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
示例 1:
输入: s ="egg",
t ="add"
输出: true
示例 2:
输入: s ="foo",
t ="bar"
输出: false
示例 3:
输入: s ="paper",
t ="title"
输出: true
说明:
你可以假设 s 和 t 具有相同的长度。
法一:双字符映射
用一个映射m1映射从s中对应的t中的字符,在用一个映射m2映射从t中对应的s中的字符,
依据m1和m2加一些逻辑设计即可
class Solution {
public:
bool isIsomorphic(string s, string t) {
if(s == "")
return true;
map<char,char> m1,m2;
for(int i = 0; i < s.length(); i++)
{
if(m1.find(s[i]) == m1.end())
{
if(m2.find(t[i]) == m2.end()) //若字符1无映射且字符2也无映射,则把映射加上,继续判断后面的字符
{
m1[s[i]] = t[i];
m2[t[i]] = s[i];
}
else
return false;
}
else
{
if(m1[s[i]] != t[i]) //若字符1有映射且映射出的字符不是字符2,则返回false
return false;
}
}
return true;
}
};
效率:
75.80%
法二:上一次出现位置映射
由于字符只有256个,所以我们只需要用一个长为256的int数组记录对应字符上一次出现的位置即可
用m1记录s中对应字符上一次出现的位置,m2记录t中对应字符上一次出现的位置
由于m1和m2初始化为0,所以我们在存上一次出现的位置时,需要存位置+1,这样才不会有误判
在循环中,每次只需要判断s和t中对应字符上一次出现的位置是否一样:
如果一样,则将位置更新为当前位置+1
如果不一样,则返回false
static const auto ios_sync_off=[](){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
bool isIsomorphic(string s, string t) {
int m1[256] = {0}, m2[256] = {0};
for(int i = 0; i < s.length(); i++)
{
if(m1[s[i]] != m2[t[i]])
return false;
else
{
m1[s[i]] = i+1;
m2[t[i]] = i+1;
}
}
return true;
}
};
效率:
100%