题目
难度:★★☆☆☆
类型:字符串
给定一个密钥字符串S,只包含字母,数字以及 '-'(破折号)。N 个 '-' 将字符串分成了 N+1 组。给定一个数字 K,重新格式化字符串,除了第一个分组以外,每个分组要包含 K 个字符,第一个分组至少要包含 1 个字符。两个分组之间用 '-'(破折号)隔开,并且将所有的小写字母转换为大写字母。
给定非空字符串 S 和数字 K,按照上面描述的规则进行格式化。
示例
示例 1:
输入:S = "5F3Z-2e-9-w", K = 4
输出:"5F3Z-2E9W"
解释:字符串 S 被分成了两个部分,每部分 4 个字符;注意,两个额外的破折号需要删掉。
示例 2:
输入:S = "2-5g-3-J", K = 2
输出:"2-5G-3J"
解释:字符串 S 被分成了 3 个部分,按照前面的规则描述,第一部分的字符可以少于给定的数量,其余部分皆为 2 个字符。
提示
S 的长度不超过 12,000,K 为正整数
S 只包含字母数字(a-z,A-Z,0-9)以及破折号'-'
S 非空
解答
观察字符串秘钥的格式化方式,可以看到有以下特点:
编码完成的字符串与输入字符串中“-”所在的位置和数量无关;
编码完成的字符串中字母均为大写;
编码完成的字符串用“-”分割,除了第一项外,其他各项子串的长度均为K,如果字母总长度恰好是K的整数倍,则第一项子串长度与其他子串均相等。
因此,我们在编码过程中的流程是:
将输入字符串中所有的“-”都去掉,并且将所有小写字母变为大写;
我们通过定义起始指针和终止指针,两个指针的范围均在0与输入字符串长度之间,这两个指针用来定位输入字符串的某一子串,通过遍历输入字符串获得格式化秘钥用“-”分开的各项子串,装在一个列表中,最后用“-”连接起来:
(1)起始指针的初始化值为零,终止指针的初始化取决于输入秘钥去“-”后的长度length能否被K整除,如果能,则为K,如果不能,则为length除以K取余,总之,要保证裁剪下来第一个子串后,剩余的部分均能被等长得裁成若干长度为K的子串,将当前子串加入到结果列表中;
(2)每次裁剪下一个子串后,将起始指针移动到终止指针处,终止指针移动到其后K个字符的位置,保证和上一次迭代裁下的字符串相接;
(3)当终止指针大于去“-”后的秘钥长度length时,即可跳出循环。将结果列表中的所有子串用“-”连接起来。
class Solution:
def licenseKeyFormatting(self, S, K):
s_long = S.replace('-', '').upper() # 去掉字符串中所有“-”,并将所有字符变为大写
length = len(s_long) # 字母长度
start = 0 # 起始位置
end = K if length % K == 0 else length % K # 根据情况设置字符串结尾
res = [] # 结果列表
while end <= length: # 当下标合法时
res.append(s_long[start: end]) # 将当前裁下来的子串放进列表
start, end = end, end+K # 更新起始和结束位置下标
return '-'.join(res) # 将列表中的字符串用“-”连接起来
如有疑问或建议,欢迎评论区留言~