/** * https://leetcode.cn/problems/isomorphic-strings/?envType=study-plan-v2&envId=top-interview-150 * @param {string} s * @param {string} t * @return {boolean} */ const isIsomorphic = function (s, t) { }; /* s和t的长度是一致的,s中的字符会按照某种关系映射到t,比如: a->b, b->c,但是不会出现a->c, b->c这种多个字符映射同一个字符,如果出现 这种情况直接返回false,也不会出现a->b, a->c这种一个字符有多个映射的情况,如果有直接返回false。 思路: 同时遍历s和t,s[i]作为hashTable的key,t[i]作为hashTable的值,如果s[i] 在hashTable中存在,检查其对应的value是否和 t[i]一致,如果不一致,就出现了 a-b, a->c这种一个字符出现多映射的情况,直接返回false,最后遍历一遍hashtable,检查是否存在,多个 value相同的情况,如果出现则表明出现了,a-c,b->c这种多个字符映射到同一个字符的情况 */ function f1(s, t) { const map = new Map(); for (let i = 0; i < s.length; i++) { if (map.has(s[i])) { if (map.get(s[i]) !== t[i]) return false; } else { map.set(s[i], t[i]); } } // 利用set查看map的value是否有重复 const set = new Set(); // eslint-disable-next-line no-unused-vars for (const [_, value] of map) { if (set.has(value)) return false; set.add(value); } return true; } /* 我们在处理a->b,a->c这种多映射的情况非常好处理,一次遍历就行,但是在遇到a->c,b->c这种被多个字符映射的情况需要遍历 一遍map的所有value,这无疑增加了复杂度,所以可以再增加一个set用来储存哪些字符应该被映射过了,如果出现了一个没有映射 的字符,但是它要映射的那个字符在set中已经存在,直接返回false,英文出现了多个字符映射到同一个字符的情况 */ function f2(s, t) { // 创建两个map,一个储存字符的映射,一个储存哪些字符已经被映射过了 const charMap = new Map(); const hasBeenMap = new Set(); for (let i = 0; i < s.length; i++) { if (charMap.has(s[i])) { if (charMap.get(s[i]) !== t[i]) return false; } else { // 检查t[i]是否已经被映射 if (hasBeenMap.has(t[i])) return false; charMap.set(s[i], t[i]); // 将映射关系加入 charMap hasBeenMap.add(t[i]); // 将 t[i] 标记为已映射 } } return true; }