205. 同构字符串
题目
给定两个字符串 s 和 t ,判断它们是否是同构的。
如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。
每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。
提示:
- 1 <= s.length <= 5 * 10^4
- t.length == s.length
- s 和 t 由任意有效的 ASCII 字符组成
AC代码
// 通过判断什么时候出现不同字符
class Solution {
public:bool isIsomorphic(string s, string t) {map<char,int>S;map<char,int>T;int ss=0,tt=0;for(int i=0;i<s.size();i++){if(!S[s[i]]) S[s[i]]=++ss; // S串 中新的字符出现,标记if(!T[t[i]]) T[t[i]]=++tt; // T串 中新的字符出现,标记if(S[s[i]]!=T[t[i]]) return false; // 字符标记不同,则字符规律不同}return true;}
};
1309. 解码字母到整数映射
题目
给你一个字符串 s,它由数字(‘0’ - ‘9’)和 ‘#’ 组成。我们希望按下述规则将 s 映射为一些小写英文字符:
情况1:字符(‘a’ - ‘i’)分别用(‘1’ - ‘9’)表示。
情况2:字符(‘j’ - ‘z’)分别用(‘10#’ - ‘26#’)表示。
返回映射之后形成的新字符串。
题目数据保证映射始终唯一。
提示:
- 1 <= s.length <= 1000
- s[i] 只包含数字(‘0’-‘9’)和 ‘#’ 字符。
- s 是映射始终存在的有效字符串。
AC代码
class Solution {
public:string freqAlphabets(string s) {string ans;int i;for(i=0;i<s.size();i++){int f=0;if(i+2<s.size()&&isdigit(s[i])&&isdigit(s[i+1])&&s[i+2]=='#') // 出现 情况 2{int x=(s[i]-'0')*10+(s[i+1]-'0');ans+=x+'a'-1;f=1; // 跳过已使用字符}else // 出现 情况 1{int x=(s[i]-'0');ans+=x+'a'-1;}if(f==1) i=i+2; // 对下标操作,跳过已使用字符}return ans;}
};
91. 解码方法
题目
一条包含字母 A-Z 的消息通过以下映射进行了 编码 :
“1” -> ‘A’
“2” -> ‘B’
…
“25” -> ‘Y’
“26” -> ‘Z’
然而,在 解码 已编码的消息时,你意识到有许多不同的方式来解码,因为有些编码被包含在其它编码当中(“2” 和 “5” 与 “25”)。
例如,“11106” 可以映射为:
“AAJF” ,将消息分组为 (1, 1, 10, 6)
“KJF” ,将消息分组为 (11, 10, 6)
消息不能分组为 (1, 11, 06) ,因为 “06” 不是一个合法编码(只有 “6” 是合法的)。
注意,可能存在无法解码的字符串。
给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数 。如果没有合法的方式解码整个字符串,返回 0。
题目数据保证答案肯定是一个 32 位 的整数。
提示:
- 1 <= s.length <= 100
- s 只包含数字,并且可能包含前导零。
AC代码
class Solution {
public:int numDecodings(string s) {if(s.size()==0||s[0]=='0')return 0;vector<int>dp(s.size()+1,0);dp[0] = 1;for(int i=1;i<=s.size();i++){dp[i] = s[i-1]=='0' ? 0 : dp[i-1]; // 当前一位为 '0'时,则无法与当前形成一个字符,无法继承前一位的种类,否则继承前一位的种类if(i > 1 && (s[i-2] == '1' || (s[i-2] == '2' &&s[i-1]<= '6'))) // 当前一位与前二位可以形成,则继承前二位的种类{dp[i] += dp[i-2];}}return dp[s.size()];}
};
200. 岛屿数量
题目
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
提示:
- m == grid.length
- n == grid[i].length
- 1 <= m, n <= 300
- grid[i][j] 的值为 ‘0’ 或 ‘1’
AC代码
// dfs 向各个可行方向行走
class Solution {
public:int n,m;int numIslands(vector<vector<char>>& grid) {int ans=0;n=grid.size(),m=grid[0].size();queue< pair<int,int> >q;map<pair<int,int> ,int >mp;for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(grid[i][j]=='1'){ans++;dfs(grid,i,j);}}}return ans;}void dfs(vector<vector<char> >& grid,int x,int y){grid[x][y]='0';if(x-1>=0&&grid[x-1][y]=='1') dfs(grid,x-1,y);if(y-1>=0&&grid[x][y-1]=='1') dfs(grid,x,y-1);if(x+1<n&&grid[x+1][y]=='1') dfs(grid,x+1,y);if(y+1<m&&grid[x][y+1]=='1') dfs(grid,x,y+1);}
};
639. 解码方法 II
题目
一条包含字母 A-Z 的消息通过以下的方式进行了 编码 :
‘A’ -> “1”
‘B’ -> “2”
…
‘Z’ -> “26”
要 解码 一条已编码的消息,所有的数字都必须分组,然后按原来的编码方案反向映射回字母(可能存在多种方式)。例如,“11106” 可以映射为:
“AAJF” 对应分组 (1 1 10 6)
“KJF” 对应分组 (11 10 6)
注意,像 (1 11 06) 这样的分组是无效的,因为 “06” 不可以映射为 ‘F’ ,因为 “6” 与 “06” 不同。
除了 上面描述的数字字母映射方案,编码消息中可能包含 '’ 字符,可以表示从 ‘1’ 到 ‘9’ 的任一数字(不包括 ‘0’)。例如,编码字符串 "1" 可以表示 “11”、“12”、“13”、“14”、“15”、“16”、“17”、“18” 或 “19” 中的任意一条消息。对 “1*” 进行解码,相当于解码该字符串可以表示的任何编码消息。
给你一个字符串 s ,由数字和 ‘*’ 字符组成,返回 解码 该字符串的方法 数目 。
由于答案数目可能非常大,返回 10^9 + 7 的 模 。
提示:
- 1 <= s.length <= 105
- s[i] 是 0 - 9 中的一位数字或字符 ‘*’
AC代码
class Solution {
public:int numDecodings(string s) {int n=s.size();if(n==0||s[0]=='0') return 0;if(n==1){if(s[0]=='*') return 9;else return 1;}vector<long long > dp(n+1);dp[0]=1;dp[1]= s[0]=='*' ? 9 : 1; // 第一个字符处理char a,b;for(int i=2;i<=n;i++) // 从第二个字符开始,列举出所有当前位与前一位的情况{a=s[i-2],b=s[i-1];if(b=='*') dp[i]+=9*dp[i-1]; // 当前为字符为 '*',继承前一位种类的 9 倍else if(b>'0') dp[i]+=dp[i-1]; // 当前字符不为 '0'和'#',继承前一位种类if(a=='*') // 前一位为 '*'{if(b=='*') // 当前字符为 '*'{dp[i]+=15*dp[i-2];}else if(b<='6') // 当前字符不为 '*',且小于 6 {dp[i]+=2*dp[i-2];}else dp[i]+=dp[i-2]; // // 当前字符不为 '*',且大于 6 }else if(a=='1'||a=='2') // 前一位为 '1' 或 '2'{if(b=='*') // 当前字符为'*'{dp[i]+= a=='1' ? 9*dp[i-2] : 6*dp[i-2];}else if((a-'0')*10 + b-'0' <=26) // 当前字符不为'*',判断是否成立{dp[i]+=dp[i-2];}}dp[i]%=1000000007; // 取模}return (int)dp[n];}
};