• LeetCode算法题-Isomorphic Strings(Java实现)


    这是悦乐书的第191次更新,第194篇原创

    01 看题和准备

    今天介绍的是LeetCode算法题中Easy级别的第50题(顺位题号是205)。给定两个字符串s和t,确定它们是否是同构的。如果s中的字符可以替换为t,则两个字符串是同构的。

    所有出现的字符必须替换为另一个字符,同时保留字符的顺序。 没有两个字符可以映射到相同的字符,但字符可以映射到自身。例如:

    输入:s =“egg”,t =“add”
    输出:true

    输入:s =“foo”,t =“bar”
    输出:false

    输入:s =“paper”,t =“title”
    输出:true

    注意:可以假设s和t都具有相同的长度。

    本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

    02 第一种解法

    因为题目已经假设两个字符串的长度是相等的,所以不用考虑特殊情况。

    使用两个HashMap,分别存储字符串s和字符串t的每一位字符,再使用两个新的字符串str和str2,分别存储其对应字符的结构,如果字符已经存在,则取出之前存的下标添加到str或str2中,如果是新出现,就把当前的下标添加到str或str2中。最后得到的str和str2就是s、t所表示的结构,如果str和str2相等,则返回true,否则返回false。

    public boolean isIsomorphic(String s, String t) {
        Map<Character, Integer> map = new HashMap<>();
        String str = "";
        for (int i=0; i<s.length(); i++) {
            if (map.containsKey(s.charAt(i))) {
                str = str + map.get(s.charAt(i));
            } else {
                map.put(s.charAt(i), i);
                str += i;
            }
        }
        Map<Character, Integer> map2 = new HashMap<>();
        String str2 = "";
        for (int j=0; j<t.length(); j++) {
            if (map2.containsKey(t.charAt(j))) {
                str2 = str2 + map2.get(t.charAt(j));
            } else {
                map2.put(t.charAt(j), j);
                str2 += j;
            }
        }
        return str.equals(str2);
    }
    

    时间复杂度:因为for循环中使用了HashMap的containsKey方法,而此方法最好的情况就是要判断的key正好是第一位,则containsKey方法的时间复杂度是O(1),最坏的情况是要判断的key在最后一位,则containsKey方法的时间复杂度是O(n)。因此,此解法的时间复杂度最好情况是O(n),最坏情况是O(n^2)。

    空间复杂度:O(n)

    03 第二种解法

    依旧使用两个HashMap,同样是将两个字符串的各个字符放入map中,不过由第一种解法的分开放变成同时放,如果在进行put的时候,有两种情况:当前字符在map中不存在的时候,返回null;当前字符在map中存在的时候,返回此字符作为key所关联的之前的value。如果两边的字符进行put操作而不相等,即说明此字符在两个map中的其中一个已经出现过一次,但是另外一个没出现过,也就表示两字符串的结构是不同的。

    public boolean isIsomorphic2(String s, String t) {
        Map<Character, Integer> map = new HashMap<>();
        Map<Character, Integer> map2 = new HashMap<>();
        for (Integer i=0; i<s.length(); i++) {
            if (map.put(s.charAt(i), i) != map2.put(t.charAt(i), i)) {
                return false;
            }
        }
        return true;
    }
    

    04 第三种解法

    只使用一个HashMap。思路与上面两种解法类似,不过是将字符串s的各个字符当成了map的key,将字符串t的各个字符当成map的value。只要map中存在当前的字符key,那么其所对应的value应该和另外一个字符串的当前字符相等,否则就是结构不同。

    public boolean isIsomorphic3(String s, String t) {
        HashMap<Character, Character> map = new HashMap<>();
        int size = s.length();
        for (int i = 0; i < size; i++) {
            if (map.containsKey(s.charAt(i))) {
                if (t.charAt(i) != map.get(s.charAt(i))) {
                    return false;
                }
            } else {
                if (map.containsValue(t.charAt(i))) {
                    return false;
                }
                map.put(s.charAt(i), t.charAt(i));
            }
        }
        return true;
    }
    

    05 第四种解法

    对于上面的解法使用HashMap来存字符,我们可以只用数组来替代,因为组成字符串的字符类型有限,ASCII码只有256个字符,所以我们预先定义好两个大小为256的整型数组,创建后两数组中的元素初始值都是0。此时,我们使用for循环对字符串s进行遍历,当前字符所表示的十进制值当做是数组的索引,如果该索引分别对应的值不相等,则说明两字符串不是同结构,否则,就将循环内的指针i作为其索引对应的值。其中i是从0开始的,但是数组初始化后其内所有元素都是默认值0,所以需要加1来区别默认值0。

    public boolean isIsomorphic4(String s, String t) {
        int[] m1 = new int[256];
        int[] m2 = new int[256];
        for (int i = 0; i < s.length(); i++) {
            if (m1[s.charAt(i)] != m2[t.charAt(i)]) return false;
            m1[s.charAt(i)] = i + 1;
            m2[t.charAt(i)] = i + 1;
        }
        return true;
    }
    

    此解法时间复杂度是O(n),空间复杂度是O(1)。

    06 小结

    算法专题目前已连续日更超过一个月,算法题文章50+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

    以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

  • 相关阅读:
    Go学习2-切片
    Go学习1-MOD
    lua学习之逻辑运算符not,and,or
    google protobuf c++ 反射
    我要谴责一下,你们复制别人的答案好歹仔细看看
    远程登录redis
    openssl进行RSA加解密(C++)
    linux通过进程名查看其占用端口
    简体字丶冯|服务网关kong-docker安装
    简体字冯|docker-安装docker私有库
  • 原文地址:https://www.cnblogs.com/xiaochuan94/p/10062040.html
Copyright © 2020-2023  润新知