题目1:145.字符串解压缩
问题描述
小U拿到了一个通过特殊方式压缩的字符串,其中每个字母后面可能跟着一个数字,这个数字表示该字母在解压后的字符串中需要重复的次数。如果一个字母后面没有跟随数字,那么该字母在解压后的字符串中只出现一次。请帮助小U解压这个字符串并输出最终的解压结果。
测试样例
输入:s = "a2b3c4"
输出:'aabbbcccc'
解析思路
这题主要是一个字符串处理问题,需要考虑的点有两个:1. 如何判断当前字母后是否为数字,以确定当前字母重复多少次;2. 若当前字母后是两位及以上的数字,如何处理。
首先开始遍历整个字符串,同时用两个变量cur_char和cur_num分别记录当前正在处理的字母和数字,首先都置为空。
- 如果当前字符是字母,先判断cur_char是否已经记录有字母,若有,说明前一个记录的字母没有数字跟随,可以直接加入最终答案,因此将其拼接到最终答案的字符串上,然后令cur_char等于当前字符。
- 如果当前字符是数字,先判断下一位字符是否也是数字,如果是,则先把当前数字拼接到cur_num,然后直接continue到下一循环,直到下一字母前的数字都被记录上。之后,由于此时cur_char必有已被记录的字母,因此直接循环cur_num次,让cur_char被拼接到最终答案的字符串上。然后,令cur_char和cur_num都置为空,等待下一次处理。
- 退出循环后,要再判断一次cur_char目前是否记录有字母,若有,拼接到最终答案上,此处是处理输入字符串是以字母结尾的情况,因为上述的循环中是根据后一位字符来处理前一位字符,无法照顾到末尾字母。
完整代码如下:
def solution(s: str) -> str:
ans = ''
cur_char = ''
cur_num = ''
for i in range(len(s)):
if s[i].isdigit() == False:
if cur_char != '':
ans += cur_char
cur_char = s[i]
else:
if i < len(s) - 1 and s[i+1].isdigit():
cur_num += s[i]
continue
cur_num += s[i]
for _ in range(int(cur_num)):
ans += cur_char
cur_char = ''
cur_num = ''
if cur_char != '':
ans += cur_char
return ans
题目2:128.找出最长的神奇数列
问题描述
小F是一个好学的中学生,今天他学习了数列的概念。他在纸上写下了一个由 0 和 1 组成的正整数序列,长度为 n。这个序列中的 1 和 0 交替出现,且至少由 3 个连续的 0 和 1 组成的部分数列称为「神奇数列」。例如,10101 是一个神奇数列,而 1011 不是。现在,小F想知道在这个序列中,最长的「神奇数列」是哪一个。你能帮他找到吗?
如果有多个神奇数列,那么输出最先出现的一个。
测试样例
输入:inp = "0101011101"
输出:'010101'
解析思路
这一题与上一题类似,都是在遍历的途中同时判断条件是否满足、并记录答案。假设我们目前已经找到一个最长神奇数列 inp[i:j+1],说明 inp[j] = inp[j+1],若继续从 i+1 开始遍历神奇数列的首位,直到 j+1 之前都会比 inp[i:j+1] 短,因此可以直接从 j+1 开始继续遍历。
因此考虑使用一轮循环遍历神奇数列的末位 j,另设一变量 i 记录神奇数列的首位。每轮循环开始时,先判断目前找到的神奇数列是否是最长神奇数列,若是,记录 i、j和目前最长长度;接着判断新遍历到的末位的后一位是否符合神奇数列的规则,即是否有 inp[j] = inp[j+1],若是,令 i = j+1。
完整代码如下:
def solution(inp):
i, max_len = 0, 2
max_i, max_j = 0, 0
for j in range(len(inp)):
if j - i + 1 > max_len:
max_i = i
max_j = j
max_len = j - i + 1
if j != len(inp) - 1 and \
(int(inp[j]) == int(inp[j + 1])):
i = j + 1
if max_i == 0 and max_j == 0:
return ""
return inp[max_i : max_j + 1]