LeetCode面试经典150题之同构字符串

文章讲述了如何使用C++实现一个名为`isIsomorphic`的函数,判断两个字符串是否可以通过一对一映射转换成彼此,通过构建两个哈希表`s2t`和`t2s`检查是否存在一对多或多对一的映射情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定两个字符串 s 和 t ,判断它们是否是同构的。

如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。

每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

简单来说题目仅允许一对一的映射,一对多和多对一是不允许的。所以我们需要在判别的时候分别引入一对多和多对一的判别。

我们先把框架搭好:

class Solution {
public:
    bool isIsomorphic(std::string s, std::string t) 
    {
        std::unordered_map<char, char> s2t;
        std::unordered_map<char, char> t2s;
        int length = s.size();
        for (int i = 0; i < length; i++)
        {
            //将要写入判别多对一和一对多映射的代码
        }
        return true;
    }
};

我们创建了两个哈希表:一个是s2t,表示s到t的映射,其键是s,值是t

另一个是t2s,表示t到s的映射,其键是t,值是s

那一对多和多对一的映射判断要怎么写呢,我们单从一对多来看,当我们写出来一对多的判断情况,多对一的判断也就水到渠成了。

我先把代码贴出来,然后再看着代码一点点解释:

s2t.find(s[i]) != s2t.end() && s2t[s[i]] != t[i] 

 这个代码是什么意思,我们庖丁解牛:.find()成员函数是用于搜索容器中的某个元素,在哈希表中表现为搜索键,如果寻到目标键,返回指向该键的迭代器,如果没有找到,返回该容器的end()。

所以&&前面的判断就是判断s2t中是否能找到s字符中的第i个字符,我们把他称之为X,其映射我们称之为Y1。那么右边的就是判断s2t这个哈希表内的键为X的字符映射Y1和此时t字符串中映射位置的字符Y2是否相等,如果相等,自然而然是一对一的映射,因为至少从目前来看X全部映射到Y1上。

但是如果映射出来是Y2,也就是不相等,那么说明s中的字符X映射到t中有Y1和Y2两个映射,就是一对多。

因此我们就可以写出来for循环之中的语句:

class Solution {
public:
    bool isIsomorphic(std::string s, std::string t) 
    {
        std::unordered_map<char, char> s2t;
        std::unordered_map<char, char> t2s;
        int length = s.size();
        for (int i = 0; i < length; i++)
        {

            //如果存在一对多或多对一映射
            //具体:1.在s->t的映射中找到了有该字母的映射,而原有s2t中的映射对应t中的映射并非此时t的值,即一对多
            //      2.t->s的映射中找到了该字母的映射,而原有t2s的映射中对应的s并非此时s的值,即多对一
            if (s2t.find(s[i]) != s2t.end() && s2t[s[i]] != t[i] ||
                t2s.find(t[i]) != t2s.end() && t2s[t[i]] != s[i])
                return false;
            s2t[s[i]] = t[i];
            t2s[t[i]] = s[i];
        }
        return true;
    }
};

如果检测一对多和多对一,那么对着来写就可以了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值