( 字符串) 205. 同构字符串 ——【Leetcode每日一题】
❓205. 同构字符串
难度:简单
给定两个字符串 s
和 t
,判断它们是否是同构的。
如果 s
中的字符可以按某种映射关系替换得到 t
,那么这两个字符串是同构的。
每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。
示例 1:
输入:s = “egg”, t = “add”
输出:true
示例 2:
输入:s = “foo”, t = “bar”
输出:false
示例 3:
输入:s = “paper”, t = “title”
输出:true
提示:
- 1 < = s . l e n g t h < = 5 ∗ 1 0 4 1 <= s.length <= 5 * 10^4 1<=s.length<=5∗104
- t.length == s.length
s
和t
由任意有效的 ASCII 字符组成
💡思路:
法一:定长数组
由于 s
和 t
由任意有效的 ASCII 字符组成,ASCII 对应的十进制为 0 ~ 255
,所以可以定义两个长度为256
的数组,就能包括所有字符:
- 数组中记录一个字符上一次出现在字符串中的位置;
- 如果两个字符串中的字符上一次出现的位置一样,那么就属于同构。
法二:哈希表
由于不同字符不能映射到同一个字符上,所以两个字符串的映射关系都必须一一对应,不能出现一对多的情况,这里设置两个哈希表,分别存储两个字符串中已建立映射关系的字符:
- 同时遍历字符串
s
和字符串t
的相同位置,建立映射关系; - 如果
s
的字符已经在哈希表中,则判断t
对应位置的字符是否等于哈希表中的映射,如果不等,则返回false
,相等则继续遍历。 - 如果字符串
s
和t
的字符都不在哈希表中,则将s
和t
对应位置的映射关系存储到哈希表中; - 否则不是同构字符串,返回
false
。 - 最后返回
true
。
🍁代码:(Java、C++)
法一:定长数组
Java
class Solution {
public boolean isIsomorphic(String s, String t) {
int[] preIndexOfS = new int[256];
int[] preIndexOfT = new int[256];
for(int i = 0; i < s.length(); i++){
char sc = s.charAt(i), tc = t.charAt(i);
if(preIndexOfS[sc] != preIndexOfT[tc]){
return false;
}
preIndexOfS[sc] = i + 1;
preIndexOfT[tc] = i + 1;
}
return true;
}
}
C++
class Solution {
public:
bool isIsomorphic(string s, string t) {
vector<int> preIndexOfS(256);
vector<int> preIndexOfT(256);
for (int i = 0; i < s.size(); i++) {
if (preIndexOfS[s[i]] != preIndexOfT[t[i]]) {
return false;
}
preIndexOfS[s[i]] = i + 1;
preIndexOfT[t[i]] = i + 1;
}
return true;
}
};
法二:哈希表
Java
class Solution {
public boolean isIsomorphic(String s, String t) {
Map<Character, Character> mapping = new HashMap<>();
Set<Character> setting = new HashSet<>();
for(int i = 0; i < s.length(); i++){
char sc = s.charAt(i), tc = t.charAt(i);
if(mapping.containsKey(sc)){
if(mapping.get(sc) != tc) return false;
}else if(!setting.contains(tc)){
mapping.put(sc, tc);
setting.add(tc);
}else{
return false;
}
}
return true;
}
}
C++
class Solution {
public:
bool isIsomorphic(string s, string t) {
unordered_map<char, char> mapping;
unordered_set<char> setting;
for(size_t i = 0; i < s.size(); i++){
if(mapping.find(s[i]) != mapping.end()){
if(mapping[s[i]] != t[i]) return false;
}else if(setting.find(t[i]) == setting.end()){
mapping.insert({s[i], t[i]});
setting.insert(t[i]);
}else{
return false;
}
}
return true;
}
};
🚀 运行结果:
🕔 复杂度分析:
- 时间复杂度:
O
(
n
)
O(n)
O(n),其中
n
为字符串s
的长度。 - 空间复杂度:
O
(
S
)
O(S)
O(S),其中
S
为字符集大小。法一:我们使用了一个长度为256
的数组,存储每个字符出现的次数。法二:哈希表存储字符的空间取决于字符串的字符集大小,最坏情况下每个字符均不相同。
题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我 leetCode专栏,每日更新!