Isomorphic Strings
Given two strings s and t, determine if they are isomorphic.
Two strings are isomorphic if the characters in s can be replaced to get t.
All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself.
For example,
Given "egg"
, "add"
, return true.
Given "foo"
, "bar"
, return false.
Given "paper"
, "title"
, return true.
Note:
You may assume both s and t have the same length.
分析:同构字符串必须满足,s字符串中相同的字符对应t字符串中相同的字符,s字符串中不同的字符对应t字符串中不同的字符。
代码如下:
class Solution { public: bool isIsomorphic(string s, string t) { char map_s[128] = { 0 }; char map_t[128] = { 0 }; int len = s.size(); for (int i = 0; i < len; ++i) { if (map_s[s[i]]!=map_t[t[i]]) return false; map_s[s[i]] = i+1; map_t[t[i]] = i+1; } return true; } };
可参考解法:
记录遍历s的每一个字母,并且记录s[i]到t[i]的映射,当发现与已有的映射不同时,说明无法同构,直接return false。然后交换s和t的位置再重来一遍,这样保证s和t之间的双向映射。
class Solution { public: bool isIsomorphic(string s, string t) { if (s.length() != t.length()) return false; map<char, char> mp; for (int i = 0; i < s.length(); ++i) { if (mp.find(s[i]) == mp.end()) mp[s[i]] = t[i]; else if (mp[s[i]] != t[i]) return false; } mp.clear(); for (int i = 0; i < s.length(); ++i) { if (mp.find(t[i]) == mp.end()) mp[t[i]] = s[i]; else if (mp[t[i]] != s[i]) return false; } return true; } };
题意为 判断一个字符串中是否可以由另一个字符串中的字符替换而来。
如果直接尝试替换的话实现比较麻烦,可以对两个字符串分解进行转换,看转换后的结果是否一致。
依次用‘0’, ‘1‘...替换字符串出现的字符,如 ’abbc‘可以替换为’0112‘。需要设置一张转换表,记录转换后每个字符对应的替代字符:
class Solution { public: string transferStr(string s){ char table[128] = {0}; char tmp = '0'; for (int i=0; i<s.length(); i++) { char c = s.at(i); if (table[c] == 0) { table[c] = tmp++; } s[i] = table[c]; } return s; } bool isIsomorphic(string s, string t) { if (s.length() != t.length()) { return false; } if (transferStr(s) == transferStr(t)) { return true; } return false; } };
其他:
class Solution { public: bool isIsomorphic(string s, string t) { const size_t n = s.size(); if ( n != t.size()) return false; unsigned char forward_map[256] = {}, reverse_map[256] = {}; for ( int i=0; i < n; ++i) { unsigned char c1 = s[i]; unsigned char c2 = t[i]; if ( forward_map[c1] && forward_map[c1] != c2) return false; if ( reverse_map[c2] && reverse_map[c2] != c1) return false; forward_map[c1] = c2; reverse_map[c2] = c1; } return true; } };
3 lines 3ms C solution
bool isIsomorphic(char* s, char* t) { static char n[512],*m = n + 256; return (!*s && !*t && memset(n,0,512)) || (((!(m[*s] || n[*t] || !(m[*s] = *t, n[*t] = *s)) || (m[*s] == *t && n[*t] == *s)) || !memset(n,0,512)) && isIsomorphic(s+1,t+1)); }
3ms O(n) C solution:The idea is to use two arrays to store the mappings between corresponding characters of s and t.
bool isIsomorphic(char* s, char* t) { char map[256], rmap[256]; memset(map, 0, sizeof map); memset(rmap, 0, sizeof rmap); for ( ; *s; ++s, ++t) if (!map[*s]) { if (rmap[*t]) // another character already maps to *t return false; map[*s] = *t; rmap[*t] = *s; } else if (map[*s] != *t) return false; return true; }