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];
}
};