算法练习帖--41--同构字符串(Java)

同构字符串

一、题目简介

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

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

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

示例 1:
输入:s = "egg", t = "add"
输出:true
示例 2:
输入:s = "foo", t = "bar"
输出:false
示例 3:
输入:s = "paper", t = "title"
输出:true
提示:
可以假设 s 和 t 长度相同。

2.解决方法

  1. 哈希表
public boolean isIsomorphic(String s, String t) {
    
    
         int sL=s.length();
         int tL=t.length();
         //排除不可能为true的情况
         if(sL!=tL){
    
    
             return false;
         }
        HashMap<Character, Character> map = new HashMap<>();
        for (int i = 0; i < sL; i++) {
    
    
            if(!map.containsKey(s.charAt(i))){
    
    
            	//不包含这个key
                if(map.containsValue(t.charAt(i))){
    
    
                	//包含了这个value直接返回false
                	//因为不能多对一
                    return  false;
                }
                //没有key和已经对应的value就将这个key-value存入hash表中
                map.put(s.charAt(i),t.charAt(i));
                continue;
            }
            //包含key的时候就要比较value和t.charAt(i)
            //必须相等才满足同构
            if(map.get(s.charAt(i))!=t.charAt(i)){
    
    
                return false;
            }
        }
        return true;
    }

2. char数组

class Solution {
    
    
    public  boolean isIsomorphic(String s, String t) {
    
    
        int sL = s.length();
        int tL = t.length();
        //排除不可能为true的情况
        if (sL != tL) {
    
    
            return false;
        }
        //两个char数组分别存储双方对应的值
        char[] sChars = new char[256];
        char[] tChars = new char[256];
        for (int i = 0; i < sL; i++) {
    
    
             if (sChars[s.charAt(i)] != '\0'){
    
    
              	//当sChars数组当前位置存储了对应的value
                if(sChars[s.charAt(i)]!=t.charAt(i)){
    
    
                	//判断s当前字符存储过的value和t当前字符对不对应的上
                    return false;
                }
            }
            //当tChars数组存储了该key
            if((tChars[t.charAt(i)] != '\0')){
    
    
            	 //当tChars数组当前位置存储了对应的value
                if(tChars[t.charAt(i)]!=s.charAt(i)){
    
    
                	//判断t当前字符存储过的value和s当前字符对不对应的上
                    return false;
                }
            }
            //赋值相当于key-value,而且是双向的
            //如果char[]数组有containsValue,那就一个数组就行了
            sChars[s.charAt(i)]=t.charAt(i);
            tChars[t.charAt(i)]=s.charAt(i);
        }
        return true;
    }
}
  1. 计数(评论区某大佬方法)
public boolean isIsomorphic(String s, String t) {
    
    
        char[] chars = s.toCharArray();
        char[] chart = t.toCharArray();
        int[] preIndexOfs = new int[256];
        int[] preIndexOft = new int[256];
        for (int i = 0; i < chars.length; i++) {
    
    
        	//两个字符数组当前字符对应的下标不相等直接返回false
        	//比如s="egg" t="add"
        	//preIndexOfs['e']:1,preIndexOfs['g']:3
        	//preIndexOft['a']:1,preIndexOft['d']:3
        	
        	
        	//比如s="foo" t="bar"
        	//preIndexOfs['f']:1,preIndexOfs['o']:3
        	//preIndexOft['b']:1,preIndexOft['a']:2,preIndexOft['r']:3
			
			//比较的是下标
            if (preIndexOfs[chars[i]] != preIndexOft[chart[i]]) {
    
    
                return false;
            }
            //存储s当前字符对应的下标(i+1是为了避免为0时和字符数组的初始值冲突)
            preIndexOfs[chars[i]] = i + 1;
            //存储t当前字符对应的下标
            preIndexOft[chart[i]] = i + 1;
        }
        return true;
    }

总结:从key-value key-value的双向字符对应,再到key-value-key的两个字符对应一个值的过程算法复杂度和时间复杂度也降低了很多。

猜你喜欢

转载自blog.csdn.net/Inmaturity_7/article/details/111793754