您好,欢迎来到华佗小知识。
搜索
您的当前位置:首页[leetcode 双周赛 6] 1153 字符串转化

[leetcode 双周赛 6] 1153 字符串转化

来源:华佗小知识

1153 String Transforms Into Another String 字符串转化

描述

给出两个长度相同的字符串,分别是 str1str2。请你帮忙判断字符串 str1 能不能在 零次多次 转化后变成字符串 str2。
每一次转化时,将会一次性将 str1 中出现的 所有 相同字母变成其他 任何 小写英文字母(见示例)。

只有在字符串 str1 能够通过上述方式顺利转化为字符串 str2 时才能返回 True,否则返回 False。​​

  • 示例 1:
  • 示例 2:

输入:str1 = "leetcode", str2 = "codeleet"
输出:false
解释:我们没有办法能够把 str1 转化为 str2。

  • 提示:

1 <= str1.length == str2.length <= 10^4
str1 和 str2 中都只会出现 小写英文字母

思路

转化的定义: 一次性将字符串中出现的 所有 相同字母变成其他 任何 小写英文字母
例如:aabcc --> ccbcc(a转化成c) --> eebee(c转化成e)

由上图可以看出:
转化的真正意义是 多对一映射 如此可以得出以下判断依据:

  • 判断依据一: 字符种类
    转化后的字符种类必定小于或者刚好等于转化前的字符种类
    注意:这种映射是有的, 它只能转化成小写字母, 即它只能在26个小写字母之间转化,
    所以目标字符串的字符种类不能为26(满值), 除非两字符串相等, 否则必定无法转化

  • 判断依据二: 映射表
    可以建立映射表, 查看是否为多对一的映射

代码实现

  • 使用两个HashMap来构建映射表
使用两个HashMap来构建映射表
class Solution {
    public boolean canConvert(String str1, String str2) {
        if (null == str1 | null == str2) return false;
        // 两字符串长度不一必定无法转化
        if (str1.length() != str2.length()) return false;
        // 两字符串相等 无需转化
        if (str1.equals(str2)) return true;
        
        // 求元素种类
        HashSet<Character> set = new HashSet<>();
        for (char c : str1.toCharArray()) set.add(c);
        int size1 = set.size();
        set.clear();
        for (char c : str2.toCharArray()) set.add(c);
        int size2 = set.size();
        // 转换字符串str2元素种类满26 必定无法转化
        // 转化后字符串元素种类比转化前还多
        if (size2 == 26 | size1 < size2) return false;
        
        // 建立映射表
        // str1ToStr2 存放被转化字符串的字符及其转化后字符所对应的标识label     字符 -> label 多对一
        HashMap<Character, Integer> str1ToStr2 = new HashMap<>();
        // str2Table 存放转化后字符所对应的标识label        字符 -> label 一对一
        HashMap<Character, Integer> str2Table = new HashMap<>();
        // label 转化后字符所对应的标识label
        int label = 0;
        // 遍历字符
        char c1, c2;
        for (int i = 0; i < str1.length(); i++) {
            c1 = str1.charAt(i);
            c2 = str2.charAt(i);
            
            // c1 --> c2
            // c2没有被标识
            if (!str2Table.containsKey(c2)) {
                // c1已经有转化对应字符了 c1!->c2 多对多
                if (str1ToStr2.containsKey(c1)) return false;
                // c1 -> label
                str1ToStr2.put(c1, label);
                // c2 -> label
                str2Table.put(c2, label);
                label++;
            }
            // c2已经被标识 c1没有被标识(还没有确定转化字符)
            if (!str1ToStr2.containsKey(c1)) {
                // c1 -> label -> c2
                str1ToStr2.put(c1, str2Table.get(c2));
            }
            // c1,c2都已经被标识 查看两者标识是否相同
            // c1 -> label ?-> c2
            if (str1ToStr2.get(c1) != str2Table.get(c2)) {
                return false;
            }
        }
        return true;
    }
}
  • 使用数组来构建映射表

    使用数组来构建映射表
class Solution {
    public boolean canConvert(String str1, String str2) {
        if (null == str1 | null == str2) return false;
        // 两字符串长度不一必定无法转化
        if (str1.length() != str2.length()) return false;
        // 两字符串相等 无需转化
        if (str1.equals(str2)) return true;
        
        // 求元素种类
        int n = str1.length(), size1 = 0, size2 = 0, p = 0, q = 0;
        boolean[] v1 = new boolean[30];
        boolean[] v2 = new boolean[30];
        for (int i = 0; i < n; i++) {
            p = str1.charAt(i) - 'a';
            q = str2.charAt(i) - 'a';
            if (!v1[p]) {
                size1++;
                v1[p]=true;
            }
            if (!v2[q]) {
                size2++;
                v2[q]=true;
            }
        }
        // 转换字符串str2元素种类满26 必定无法转化
        // 转化后字符串元素种类比转化前还多
        if (size2 == 26 | size1 < size2) return false;
        
        // 建立映射表
        // s1ToS2 映射表 下标表示原字符-'a' 值表示目标字符
        char[] s1ToS2 = new char[30];
        char c = '#';
        // 映射表初始化为全'#'
        for (int i = 0; i < 26; i++) s1ToS2[i] = '#';
        for (int i = 0; i < n; i++) {
            p = str1.charAt(i) - 'a';
            c = str2.charAt(i);
            
            // 该字符p还没有映射
            // 或者
            // 该字符p映射已经映射 且映射单一
            if (s1ToS2[p] == '#' | s1ToS2[p] == c) s1ToS2[p]=c;
            else return false;
        }
        
        return true;
    }
}

转载于:https://www.cnblogs.com/slowbirdoflsh/p/11356674.html

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo0.cn 版权所有 湘ICP备2023017654号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务