leetcode:205. 同构字符串

题目来源

题目描述

在这里插入图片描述

题目解析

方法一

两个字符串同构的含义就是字符串s可以唯一的映射到t,同时t也可以唯一元素到s。举个例子:

egg 和 add 同构,就意味着下边的映射成立
e -> a
g -> d
也就是将 egg 的 e 换成 a, g 换成 d, 就变成了 add

同时倒过来也成立
a -> e
d -> g
也就是将 add 的 a 换成 e, d 换成 g, 就变成了 egg

foo 和 bar 不同构,原因就是映射不唯一
o -> a
o -> r
其中 o 映射到了两个字母

我们可以利用一个map来处理映射。 对于st的映射,我们同时遍历st,假设当前遇到的字母分别是c1c2

  • 如果map[c1]不存在,那么就将c1映射到c2,即map[c1] = c2
  • 如果map[c1]存在,那么就判断map[c1]是否等于c2,也就是映射之前的映射是否和当前的映射相同

注意,我们需要映射两个方向,只验证一个方向是不可以的。比如

"badc"
"baba"
class Solution {
public:
	bool helper(string s, string t){
	    if(s.size() != t.size()){
	        return false;
	    }
	    std::map<char, char> mapper;
	    for (int i = 0; i < s.size(); ++i) {
	        char ch1 = s[i];
	        char ch2 = t[i];
	        if(mapper.count(ch1)){
	            if(mapper[ch1] != ch2){
	                return false;
	            }
	        }else{
	            mapper[ch1] = ch2;
	        }
	    }
	
	    return true;
	}
	
	bool isIsomorphic(string s, string t) {
	    return helper(s, t) && helper(t, s);
	}
};

在这里插入图片描述

方法2

解法一中,我们判断 s 和 t 是否一一对应,通过对两个方向分别考虑来解决的。

这里的话,我们找一个第三方来解决,即,按照字母出现的顺序,把两个字符串都映射到另一个集合中。

举个现实生活中的例子,一个人说中文,一个人说法语,怎么判断他们说的是一个意思呢?把中文翻译成英语,把法语也翻译成英语,然后看最后的英语是否相同即可。

将第一个出现的字母映射成 1,第二个出现的字母映射成 2

对于 egg
e -> 1
g -> 2
也就是将 egg 的 e 换成 1, g 换成 2, 就变成了 122

对于 add
a -> 1
d -> 2
也就是将 add 的 a 换成 1, d 换成 2, 就变成了 122

egg -> 122, add -> 122
都变成了 122,所以两个字符串异构。

因为 0 是我们的默认值,所以不能直接赋值为下标,而是「下标加 1」。

std::string helper(std::string& s){
    int cnt = 1;
    std::string str;
    std::map<char, int> mapper;
    for (int i = 0; i < s.size(); ++i) {
        char ch = s[i];
        if(!mapper.count(ch)){
            mapper[ch] = cnt++;
        }
        str += std::to_string(mapper[ch]);
    }
    
    return str;
}

bool isIsomorphic(string s, string t) {
    return helper(s) == helper(t);
}

在这里插入图片描述
其实我们不需要将字符串完全转换,我们可以用两个 map 分别记录两个字符串每个字母的映射。将所有字母初始都映射到 0。记录过程中,如果发现了当前映射不一致,就可以立即返回 false 了。

举个例子:

对 abaddee 和 cdbccff
    
a b a d d e e
c d b c c f f
^

当前
a -> 0
c -> 0

修改映射
a -> 1
c -> 1

a b a d d e e
c d b c c f f
  ^
    
当前
b -> 0
d -> 0   
    
修改映射
b -> 2
d -> 2

    
a b a d d e e
c d b c c f f
    ^    
当前
a -> 1 (之前被修改过)
b -> 0

出现不一致,所以两个字符串不异构 

代码如下:

bool isIsomorphic(string s, string t) {
    if(s.size() != t.size()){
        return false;
    }

    std::vector<int> mapper1(128, 0), mapper2(128, 0);
    for (int i = 0; i < s.size(); ++i) {
        char ch1 = s[i];
        char ch2 = t[i];
        
        if(mapper1[ch1] != mapper2[ch2]){
            return false;
        }else{
            //是否已经修改过,修改过就不需要再处理
            if(mapper1[ch1] == 0){ 
                mapper1[ch1] = i + 1;
                mapper2[ch2] = i + 1;
            }
        }
    }
    return true;
}

在这里插入图片描述

类似题目

题目思路
leetcode:205. 同构字符串 Isomorphic Strings
leetcode:290. 单词规律 Word Pattern
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值