Skip to content

Latest commit

 

History

History
152 lines (116 loc) · 4.3 KB

双射.md

File metadata and controls

152 lines (116 loc) · 4.3 KB

力扣383 290 265

383 赎金信

已解答 简单 相关标签 相关企业 给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

示例 1:

输入:ransomNote = "a", magazine = "b" 输出:false 示例 2:

输入:ransomNote = "aa", magazine = "ab" 输出:false 示例 3:

输入:ransomNote = "aa", magazine = "aab" 输出:true

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        HashMap<Character,Integer> map = new HashMap<>();
        for(char c: magazine.toCharArray()){
            map.put(c,map.getOrDefault(c,0)+1);
        }
        for(char c:ransomNote.toCharArray()){
            if(!map.containsKey(c) || map.get(c) == 0){
                return false;
            }
            map.put(c,map.get(c)-1);
        }
        return true;
    }
}

205. 同构字符串

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

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

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

示例 1:

输入:s = "egg", t = "add" 输出:true 示例 2:

输入:s = "foo", t = "bar" 输出:false 示例 3:

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

class Solution {
    public boolean isIsomorphic(String s, String t) {
        Map<Character,Character> s2t = new HashMap<>(),t2s = new HashMap<>();
        for(int i=0;i<s.length();i++){
            char a = s.charAt(i),b = t.charAt(i);
            if(s2t.containsKey(a) && s2t.get(a)!=b || t2s.containsKey(b) && t2s.get(b)!=a){
                return false;
            }
            s2t.put(a,b);
            t2s.put(b,a);
        }
        return true;
    }
}

290. 单词规律

给定一种规律 pattern 和一个字符串 s ,判断 s 是否遵循相同的规律。

这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。

示例1:

输入: pattern = "abba", s = "dog cat cat dog" 输出: true 示例 2:

输入:pattern = "abba", s = "dog cat cat fish" 输出: false 示例 3:

输入: pattern = "aaaa", s = "dog cat cat dog" 输出: false

class Solution {
    public boolean wordPattern(String pattern, String s) {
        String[] s_arr = s.split(" ");
        if(s_arr.length != pattern.length())    return false;
        Map<Character,String> charToStr = new HashMap<>();
        Map<String,Character> strToChar = new HashMap<>();
        for(int i = 0; i<pattern.length(); i++){
            char c = pattern.charAt(i);
            String word = s_arr[i];
            if(charToStr.containsKey(c)){
                if(!charToStr.get(c).equals(word)){
                    return false;
                }
            }
            else{
                charToStr.put(c,word);
            }
            if(strToChar.containsKey(word)){
                if(!strToChar.get(word).equals(c)){
                    return false;
                }
            }
            else{
                strToChar.put(word,c);
            }

        }
        return true;
    }
}

解题思路

首先复习一下数学中映射的相关概念定义。设集合 s , t 中的某字符为 x , y ,

单射:对于任意 x ,都有唯一的 y 与之对应。 满射:对于任意 y ,至少存在一个 x 与之对应。 双射:既是单射又是满射,又称为一一对应。

接下来,抽象理解题目给定条件,

“每个出现的字符都应当映射到另一个字符”。代表字符集合 s , t 之间是「满射」。 “相同字符只能映射到同一个字符上,不同字符不能映射到同一个字符上”。代表字符集合 s , t 之间是「单射」。 因此, s 和 t 之间是「双射」,满足一一对应。考虑遍历字符串,使用哈希表 s2t , t2s 分别记录 s→ts \rightarrow ts→t , t→st \rightarrow st→s 的映射,当发现任意「一对多」的关系时返回 false 即可