3597. 分割字符串
难度:中等
问题描述:
给你一个字符串 s,按照以下步骤将其分割为 互不相同的段 :
从下标 0 开始构建一个段。
逐字符扩展当前段,直到该段之前未曾出现过。
只要当前段是唯一的,就将其加入段列表,标记为已经出现过,并从下一个下标开始构建新的段。
重复上述步骤,直到处理完整个字符串 s。
返回字符串数组 segments,其中 segments[i] 表示创建的第 i 段。
示例 1:
输入: s = "abbccccd"
输出: ["a","b","bc","c","cc","d"]
解释:
下标 添加后 已经出现过 当前段 新段 更新后
的段 的段 是否已经出现过? 已经出现过的段
0 "a" [] 否 "" ["a"]
1 "b" ["a"] 否 "" ["a", "b"]
2 "b" ["a", "b"] 是 "b" ["a", "b"]
3 "bc" ["a", "b"] 否 "" ["a", "b", "bc"]
4 "c" ["a", "b", "bc"] 否 "" ["a", "b", "bc", "c"]
5 "c" ["a", "b", "bc", "c"] 是 "c" ["a", "b", "bc", "c"]
6 "cc" ["a", "b", "bc", "c"] 否 "" ["a", "b", "bc", "c", "cc"]
7 "d" ["a", "b", "bc", "c", "cc"] 否 "" ["a", "b", "bc", "c", "cc", "d"]
因此,最终输出为 ["a", "b", "bc", "c", "cc", "d"]。
示例 2:
输入: s = "aaaa"
输出: ["a","aa"]
解释:
下标 添加 已经 当前段 新段 更新后
后的段 出现过的段 是否已经出现过? 已经出现过的段
0 "a" [] 否 "" ["a"]
1 "a" ["a"] 是 "a" ["a"]
2 "aa" ["a"] 否 "" ["a", "aa"]
3 "a" ["a", "aa"] 是 "a" ["a", "aa"]
因此,最终输出为 ["a", "aa"]。
提示:
1 <= s.length <= 105
s 仅包含小写英文字母。
问题分析:
根据题目的描述,从0号字符开始向后拓展构建新段,在拓展时,只要该段在之前未出现过,就将其加入新段列表,并从下一个下标开始构建新段,所以从一个下标开始找出一个新段是解决问题的关键,为此设计函数struct_new_paragraph(i,s,pars),其功能是从下标i开始在字符串s中拓展新段,并将新段加入新段列表pars中,函数返回构建下一个新段的起始位置和本次生成的新段列表,这样可以反复调用本函数以拓展后续的新段。
主程序根据输入的字符串s,从索引号0开始利用struct_new_paragraph(i,s,pars)函数拓展新段,只要返回的起始位置小于字符串s的长度n,就可以不断拓展,最后将新段列表输出,即是问题的解。
程序如下:
#通过起始位置i、原字符串s和新段列表pars构造新段,返回下一个新段的起始位置和本次生成的新段列表
def struct_new_paragraph(i,s,pars):
n=len(s)
# j用于控制结束位置,所以当起位置i取到n-1时,j要取到n+1
for j in range(i+1,n+1):
a=s[i:j]
print('截取字符串:',a)
if a not in pars:
pars.append(a)
print(f'新段起始位置{j},新段列表{pars}')
return j,pars
else:
print(f'{a}已经在新段列表中')
continue
else:
print('j,pars:',n,pars)
return n,pars
#主程序
s=input('pls input s=')
pars=[]
n=len(s)
print('新段起始位置为0,新段列表为[]')
(i,pars)=struct_new_paragraph(0,s,pars)
while i<n:
i, pars = struct_new_paragraph(i, s, pars)
print(f'起始位置索引号{i}已经超过字符串{s}的最大索引号{n-1}')
print(f'最终输出新段列表为{pars}')
运行实例一
pls input s=abaacd
新段起始位置为0,新段列表为[]
截取字符串: a
新段起始位置1,新段列表['a']
截取字符串: b
新段起始位置2,新段列表['a', 'b']
截取字符串: a
a已经在新段列表中
截取字符串: aa
新段起始位置4,新段列表['a', 'b', 'aa']
截取字符串: c
新段起始位置5,新段列表['a', 'b', 'aa', 'c']
截取字符串: d
新段起始位置6,新段列表['a', 'b', 'aa', 'c', 'd']
起始位置索引号6已经超过字符串abaacd的最大索引号5
最终输出新段列表为['a', 'b', 'aa', 'c', 'd']
运行实例二
pls input s=bbbbbb
新段起始位置为0,新段列表为[]
截取字符串: b
新段起始位置1,新段列表['b']
截取字符串: b
b已经在新段列表中
截取字符串: bb
新段起始位置3,新段列表['b', 'bb']
截取字符串: b
b已经在新段列表中
截取字符串: bb
bb已经在新段列表中
截取字符串: bbb
新段起始位置6,新段列表['b', 'bb', 'bbb']
起始位置索引号6已经超过字符串bbbbbb的最大索引号5
最终输出新段列表为['b', 'bb', 'bbb']
运行实例三
pls input s=abbcccd
新段起始位置为0,新段列表为[]
截取字符串: a
新段起始位置1,新段列表['a']
截取字符串: b
新段起始位置2,新段列表['a', 'b']
截取字符串: b
b已经在新段列表中
截取字符串: bc
新段起始位置4,新段列表['a', 'b', 'bc']
截取字符串: c
新段起始位置5,新段列表['a', 'b', 'bc', 'c']
截取字符串: c
c已经在新段列表中
截取字符串: cd
新段起始位置7,新段列表['a', 'b', 'bc', 'c', 'cd']
起始位置索引号7已经超过字符串abbcccd的最大索引号6
最终输出新段列表为['a', 'b', 'bc', 'c', 'cd']
理清处理问题的逻辑顺序,合理分割其中的处理步骤,转换成对应的函数,问题必将容易解决。