问题描述
来源:LeetCode第1309题
难度:简单
给你一个字符串s,它由数字('0'-'9')和'#'组成。我们希望按下述规则将s映射为一些小写英文字符:
字符('a'-'i')分别用('1'-'9')表示。
字符('j'-'z')分别用('10#'-'26#')表示。
返回映射之后形成的新字符串。
题目数据保证映射始终唯一。
示例 1:
输入:s = "10#11#12"
输出:"jkab"
解释:"j" -> "10#" , "k" -> "11#" , "a" -> "1" , "b" -> "2".
示例 2:
输入:s = "1326#"
输出:"acz"
示例 3:
输入:s = "25#"
输出:"y"
示例 4:
输入:s =
"12345678910#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#"
输出:"abcdefghijklmnopqrstuvwxyz"
提示:
- 1<=s.length<=1000
- s[i]只包含数字('0'-'9')和'#'字符。
- s是映射始终存在的有效字符串。
问题分析
这题是让把数字解码到字符,正常情况下如果从前往后遍历字符串s计算的时候有点麻烦,因为当遇到一个数字的时候不确定他是一个单独的数字还是和后面'#'结合的。所以我们可以逆向思维,从后往前遍历,当遇到一个数字的时候他就是一个单独的数字,当遇到符号'#'的时候我们需要往前截取两个数字,也就是说'#'和前面的两个数字他们三个是一伙的。原理比较简单,基本上没什么难度,我们来看下代码
public String freqAlphabets(String s) {
StringBuilder stringBuilder = new StringBuilder();
//字符串从后往前遍历
for (int i = s.length() - 1; i >= 0; i--) {
//如果遇到字符'#',就截取他前面的两个数字
if (s.charAt(i) == '#') {
stringBuilder.append((char) ('a' + Integer.parseInt(s.substring(i - 2, i)) - 1));
i -= 2;
} else {
stringBuilder.append((char) ('a' + s.charAt(i) - '1'));
}
}
//因为是从后往前遍历的,最后需要把结果反转一下
return stringBuilder.reverse().toString();
}