题目
题目描述
你会得到一个字符串 t e x t text text 。你应该把它分成 k k k 个子字符串 ( s u b t e x t 1 , s u b t e x t 2 , ⋯ , s u b t e x t k (subtext_1, subtext_2,\cdots, subtext_k (subtext1,subtext2,⋯,subtextk) ,要求满足:
- s u b t e x t i subtext_i subtexti 是 非空 字符串
- 所有子字符串的连接等于 t e x t text text (即 s u b t e x t 1 + s u b t e x t 2 + ⋯ + s u b t e x t k = t e x t subtext_1 + subtext_2 + \cdots + subtext_k = text subtext1+subtext2+⋯+subtextk=text)
- 对于所有 i i i 的有效值( 即 1 ≤ i ≤ k 1 \leq i \leq k 1≤i≤k ) , s u b t e x t i = s u b t e x t k − i + 1 subtext_i = subtext_{k - i + 1} subtexti=subtextk−i+1 均成立
返回 k k k 可能最大值。
示例
示例 1
输入: t e x t = " g h i a b c d e f h e l l o a d a m h e l l o a b c d e f g h i " text = "ghiabcdefhelloadamhelloabcdefghi" text="ghiabcdefhelloadamhelloabcdefghi"
输出: 7 7 7
解释:我们可以把字符串拆分成 " ( g h i ) ( a b c d e f ) ( h e l l o ) ( a d a m ) ( h e l l o ) ( a b c d e f ) ( g h i ) " "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)" "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)"。
示例 2
输入: t e x t = " m e r c h a n t " text = "merchant" text="merchant"
输出: 1 1 1
解释:我们可以把字符串拆分成 " ( m e r c h a n t ) " "(merchant)" "(merchant)"。
示例 3
输入: t e x t = " a n t a p r e z a t e p z a p r e a n t a " text = "antaprezatepzapreanta" text="antaprezatepzapreanta"
输出: 11 11 11
解释:我们可以把字符串拆分成 " ( a ) ( n t ) ( a ) ( p r e ) ( z a ) ( t p e ) ( z a ) ( p r e ) ( a ) ( n t ) ( a ) " "(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)" "(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)"。
提示
1 ≤ t e x t . l e n g t h ≤ 1000 1 \leq text.length \leq 1000 1≤text.length≤1000
t e x t text text 仅由小写英文字符组成
思路
我的思路
1: 定义两个指针 i ← 0 , j ← t e x t . l e n g t h − 1 i\leftarrow 0,j\leftarrow text.length-1 i←0,j←text.length−1
2: 令 k ← 0 k\leftarrow 0 k←0
3: 当 i < = j i<=j i<=j 时
3-1: 令 t ← j t\leftarrow j t←j
3-2: 当 t e x t [ i ] ≠ t e x t [ j ] text[i]\neq text[j] text[i]=text[j] 时
3-2-1: 若 j < ⌈ i + t 2 ⌉ j<\lceil\frac{i+t}{2}\rceil j<⌈2i+t⌉,则 k ← k + 1 k\leftarrow k+1 k←k+1 并跳转到步骤 4
3-2-2: 否则 j ← j − 1 j\leftarrow j-1 j←j−1
3-2-3: 若 i = j i=j i=j,则 k ← k + 1 k\leftarrow k+1 k←k+1 并跳转到步骤 4
3-3: 若 t e x t [ i : i + ( t − j + 1 ) ] = t e x t [ j : t + 1 ] text[i:i+(t-j+1)]=text[j:t+1] text[i:i+(t−j+1)]=text[j:t+1] 则, i ← i + ( t − j + 1 ) , j ← t e x t . l e n g t h − 1 − i i\leftarrow i+(t-j+1),j\leftarrow text.length-1-i i←i+(t−j+1),j←text.length−1−i、 k ← k + 2 k\leftarrow k+2 k←k+2
3-4: 否则 j ← j − 1 j\leftarrow j-1 j←j−1 并跳转到步骤 3-2
4: 返回 k k k
改进思路
由于指针 j j j 在回退寻找与指针 i i i 所指向字符中已经遍历了一次,后续判断字串是否相等时又重复遍历了一次,因此极大增加了算法时间
以下是改进算法
1: 令 k = 0 k=0 k=0
2: 定义两个空列表 a , b a,b a,b
3: 定义指针 i = 0 i=0 i=0
4: 当 i < ⌊ t e x t . l e n g t h 2 ⌋ i<\lfloor\frac{text.length}{2}\rfloor i<⌊2text.length⌋ 时
4-1: 将 t e x t text text 的第 i i i 个字符加入列表 a a a,倒数第 i + 1 i+1 i+1 个字符加入列表 b b b
4-2: 若列表 a a a 等于列表 b b b 的逆序,则 k ← k + 2 k\leftarrow k+2 k←k+2 并清空列表 a , b a,b a,b
5: 若 t e x t . l e n g t h m o d 2 = 0 text.length\mod 2 = 0 text.lengthmod2=0,则 k ← k + 1 k\leftarrow k+1 k←k+1
6: 若 a a a 或 b b b 列表不为空,则 k ← k + 1 k\leftarrow k+1 k←k+1
7: 返回 k k k
代码实现
我的思路实现
class Solution:
def longestDecomposition(self, text: str) -> int:
lengh_text = len(text)
i, j = 0, lengh_text - 1
k, t = 0, j
while i <= j:
while text[i] != text[j]:
if j < (i+t) // 2 + 1:
return k + 1
else:
j -= 1
if i == j:
return k + 1
if text[i:i+(t-j+1)] == text[j:t+1]:
k += 2
i += t - j + 1
j = lengh_text - 1 - i
else:
j -= 1
continue
t = j
return k
改进思路实现
class Solution:
def longestDecomposition(self, text: str) -> int:
k = 0
a, b = [], []
length = len(text)
for i in range(length // 2):
a.append(text[i]), b.append(text[-(i+1)])
if a == b[::-1]:
k += 2
a.clear(), b.clear()
if length % 2 != 0 or len(a) != 0:
k += 1
return k