一.问题描述
Given a string s
formed by digits ('0'
- '9'
) and '#'
. We want to map s
to English lowercase characters as follows:
- Characters (
'a'
to'i')
are represented by ('1'
to'9'
) respectively. - Characters (
'j'
to'z')
are represented by ('10#'
to'26#'
) respectively.
Return the string formed after mapping.
It's guaranteed that a unique mapping will always exist.
Example 1:
Input: s = "10#11#12"
Output: "jkab"
Explanation: "j" -> "10#" , "k" -> "11#" , "a" -> "1" , "b" -> "2".
Example 2:
Input: s = "1326#"
Output: "acz"
Example 3:
Input: s = "25#"
Output: "y"
Example 4:
Input: s = "12345678910#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#"
Output: "abcdefghijklmnopqrstuvwxyz"
Constraints:
1 <= s.length <= 1000
s[i]
only contains digits letters ('0'
-'9'
) and'#'
letter.s
will be valid string such that mapping is always possible.
二.解题思路
方法一:正序处理
用栈来处理,迭代s的每个字符,遇到#字符(说明前面是一个三个字符组成的一个编码),弹出前两个解码的数字,并推入新解码的数。
遇到非#字符,直接将对应的解码字符推入。(可能后面有#因此推错,不过没关系,等后面迭代到#的时候会处理)
注意:正序处理会遇到单独字符0,因此记得给0也丢进解码列表里,随便给一个值。
时间复杂度:O(N).
方法二:逆序处理
先将s反转,然后迭代s中的每个元素,
如果当前迭代的字符串在解码列表里,解码,
如果不在,则和下一个字符相连组成一个字符串接着判断。
好处就是不用像方法一先推错了,然后后面要pop。
比如说对于 110#
反转:#011
迭代到#,不在解码列表,迭代下一个并相连。
0#,不在解码列表,继续
10#,在了,解码,清空字符串,下一个处理的
1,在解码列表,解码。
时间复杂度:(N).
注意,由于解码是逆序的,因此最后返回的结果还要再反转一次。
方法三:
迭代处理s,每次判断迭代后2个位置是否是#字符,是的话组合这三个字符解码,不是直接解码,
更多leetcode算法题解法: 专栏 leetcode算法从零到结束 或者 leetcode 解题目录 Python3 一步一步持续更新~
三.源码
方法一:
class Solution:
def freqAlphabets(self, s: str) -> str:
l = {}
for i in range(0,10):
l[str(i)] = chr(96+i)
for i in range(10,27):
l[str(i) + '#'] = chr(96+i)
rst=[]
for i,ch in enumerate(s):
if ch!="#":rst.append(l[ch])
else:
rst.pop()
rst.pop()
rst.append(l[s[i-2:i+1]])
return ''.join(rst)
方法二:源自leetcode demo
class Solution:
def freqAlphabets(self, s: str) -> str:
l = {}
for i in range(1,10):
l[str(i)] = chr(96+i)
for i in range(10,27):
l[str(i) + '#'] = chr(96+i)
stack = ""
out = ""
s = s[::-1]
for c in s:
stack = c + stack
if stack in l.keys():
out += l[stack]
stack = ""
return out[::-1]
方法三:from leetcode demo
class Solution:
def freqAlphabets(self, s: str) -> str:
i = 0
res = ''
while i < len(s):
if i < len(s) - 2:
if s[i+2] == '#':
res += chr(96 + int(s[i:i + 2]))
s = s[:i] + '' + s[i + 3:]
else:
res += chr(96 + int(s[i]))
s = s[:i] + '' + s[i + 1:]
else:
res += chr(96 + int(s[i]))
i += 1
return res