问题描述
小F正在学习数列的概念,并提出了一个问题:对于一个由 0 和 1 组成的正整数序列,长度为 n,找到其中最长的「神奇数列」。
什么是「神奇数列」?
- 「神奇数列」是一个交替出现的
0和1组成的子序列。 - 子序列的长度必须至少为
3。 - 如果有多个「神奇数列」长度相同,选择最先出现的一个。
输入: 一个仅包含 0 和 1 的字符串 inp。
输出: 最长的「神奇数列」。若不存在满足条件的子序列,返回空字符串 ''。
测试样例
样例 1
输入:
inp = "0101011101"
输出:
"010101"
解释:
最长的「神奇数列」是 "010101",长度为 6。
样例 2
输入:
inp = "1110101010000"
输出:
"10101010"
解释:
最长的「神奇数列」是 "10101010",长度为 8。
样例 3
输入:
inp = "1010101010101010"
输出:
"1010101010101010"
解释:
整个字符串都是一个「神奇数列」,长度为 16。
解题思路
1. 问题分解
-
识别交替字符的子序列:
遍历字符串,检查相邻的字符是否交替出现。如果交替,则将当前长度加1;否则,结束当前子序列,重新开始计数。 -
记录最长的「神奇数列」:
维护一个变量存储当前最长子序列的起始位置和长度。 -
处理边界情况:
如果序列长度小于3或整个序列中没有符合条件的「神奇数列」,则返回空字符串。
2. 实现步骤
- 遍历输入字符串
inp,判断是否为交替的0和1。 - 使用变量记录当前「神奇数列」的起始位置和长度。
- 遇到不交替的字符时,检查当前子序列长度是否超过记录的最长长度,并更新。
- 遍历结束后,再次检查最后一个子序列是否为最长的「神奇数列」。
- 返回最长的「神奇数列」。
代码实现
def solution(inp):
max_start = 0 # 最长「神奇数列」的起始位置
max_length = 0 # 最长「神奇数列」的长度
current_start = 0 # 当前「神奇数列」的起始位置
current_length = 1 # 当前子序列的长度,初始化为1
for i in range(len(inp) - 1):
if inp[i + 1] == inp[i]:
# 遇到不交替的字符,检查当前子序列是否为最长
if current_length > max_length:
max_length = current_length
max_start = current_start
# 更新为新的「神奇数列」
current_start = i + 1
current_length = 1
else:
# 交替的字符,继续增长当前子序列
current_length += 1
# 遍历结束后,再次检查最后一个子序列
if current_length > max_length:
max_length = current_length
max_start = current_start
# 提取最长的「神奇数列」
result = inp[max_start:max_start + max_length]
# 如果长度小于3,不是有效的「神奇数列」
if len(result) >= 3:
return result
else:
return ''
if __name__ == "__main__":
# 测试用例
print(solution("0101011101") == "010101") # 测试样例1
print(solution("0101011101")) # 输出: "010101"
print(solution("1110101010000") == "10101010") # 测试样例2
print(solution("1010101010101010") == "1010101010101010") # 测试样例3
代码解析
核心变量
• max_start 和 max_length:记录当前最长「神奇数列」的起始位置和长度。
• current_start 和 current_length:记录当前正在处理的子序列的起始位置和长度。
算法流程
- 遍历字符串中的每个字符:
• 如果遇到不交替的字符,结束当前子序列,并更新最长子序列的起始位置和长度。
• 如果字符交替,继续增长当前子序列的长度。
-
遍历结束后,再检查最后一个子序列是否为最长「神奇数列」。
-
根据记录的起始位置和长度,从字符串中提取子序列。
-
如果子序列长度不足 3,返回空字符串。