Leetcode题库 - 同构字符串(java语言版)

题目描述:

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

如果 中的字符可以被替换得到 ,那么这两个字符串是同构的。

所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。

示例 1:

输入: s = "egg", t = "add"

输出: true

示例 2:

输入: s = "foo", t = "bar"

输出: false

示例 3:

输入: s = "paper", t = "title"

输出: true

说明:
你可以假设 和 具有相同的长度。

    本题思路有两种,都是用map来操作,保存相应字符,进行操作

    第一种:用一个map保存两个字符串中的字符,令键为第一个字符串中的字符,值为第二字符串中的字符,然后进行判断,遍历第二个字符串,当第二个字符串中的字符不在map中能找到,就返回false,证明不是同构字符串,当都相等时,则是同构字符串。这个地方有一个问题,就是会出现多对一的映射,这种映射肯定不是同构字符串,例如,ab,aa这两个字符串,判断是,总能在map中找到第二个字符串中的字符,返回true,这样就出错了,怎么解决这个问题呢,同set,保存当作值添加进map中的第二个字符串的字符,当再次遇到这个字符(也就是set中已经存在了这个字符,证明,这就产生多对一的映射了,这样不合理,返回false),这样就可以满足所有情况了。

     第二种思路:这个很好理解,我觉得这个是比第一个还要简单的方法,不过时间复杂度能比第一个高一点。这个方法就是用两个map,一个map保存第一个字符串中字符与第二个字符串中的字符的映射,第二个map保存第二个字符串和第一个字符串的映射,然后遍历任意字符串长度(因为两个字符串相同),判断第一个字符串在第二个map中是否存在或者第二个字符串在第一个map中是否存在,任意一个不存在则返回false,最后遍历完后返回true.

     第一种思路代码:

public static void main(String[] args){
//        使用一个哈希表map维护两个字符串中字符的映射关系,同时用一个set保存映射的值
        String s = "ad";
        String t = "aa";
        char []ch1 =s.toCharArray ();
        char []ch2 =t.toCharArray ();
//        map映射用来存储第一个字符串中的字符与第二个字符串中的字符(键:第一个字符串中的字符,值:第二个字符串中的字符)
        Map<Character,Character> map = new HashMap <> (  );
//        用来去重,(当多对一的映射时,用这个处理,例如第一个字符串有两个不一样的字符,第二个字符串一样的字符,这样就形成了多对一。不是同构字符串)
        Set<Character> set = new HashSet <> (  );
        for (int i = 0;i<ch1.length;i++){
//            当map中有ch1中的字符时,判断ch2中的字符是否等于,map中ch1对应字符的值,如果不等与,则不是同构字符串
            if (map.containsKey ( ch1[i] )){
                if (ch2[i]!=map.get ( ch1[i] )){
                    System.out.println("不是同构字符串");
                    break;
                }
//                如果map没有ch1中字符对应的键
            }else{
//                然后判断集合中是否存在ch2中的字符,存在时,证明map中的键与值形成多对1的关系,也就是,map中的键不一致但值是一样的,当然不是同构字符串.
                if (set.contains ( ch2[i] )){
                    System.out.println("不是同构字符串");
                    break;
                }else {
//                    如果键不存在,并且,值也不一样,这样就将map,ch1做键,ch2做值,放到map中,并且将ch2的字符添加到set,用来判断是否存在一对多的隐射.
                    map.put ( ch1[i],ch2[i] );
                    set.add ( ch2[i] );
                }
            }
        }
        System.out.println("是同构字符串");

执行结果:

执行用时:

第二中思路代码:

 第二种方法
//用两个map分别保存1-2,2-1的映射,然后判断值是否存在与各个映射中
        Map<Character,Character> map1 = new HashMap <> (  );
        Map<Character,Character> map2 = new HashMap <> (  );
        for(int i=0;i<ch1.length;i++){
             map1.put ( ch1[i],ch2[i] );
        }
        for (int i = 0;i<ch2.length;i++){
            map2.put ( ch2[i],ch1[i] );

        }
        for (int j = 0;j<ch2.length;j++){
            if (ch1[j]!=map2.get ( ch2[j] )||ch2[j]!=map1.get ( ch1[j] )){
               System.out.println("不是同构字符串");
               break;
            }
        }
        System.out.println("是同构字符串");

执行用时:

      总结:这道题还是map的使用,个人觉得两个map好用,好理解,map和set灵活,时间复杂度低,不太好理解,map重点一定是定住各个映射,别映射错了。

2019-3-19

发布了43 篇原创文章 · 获赞 6 · 访问量 6664

猜你喜欢

转载自blog.csdn.net/weixin_37850160/article/details/88669455