刷题打卡 神奇数列| 豆包MarsCode AI刷题

68 阅读3分钟

题目描述

小F在纸上写下了一个由 01 组成的正整数序列,长度为 n。这个序列中的 10 交替出现,且至少由 3 个连续的 0 和 1 组成 的部分序列被称为「神奇数列」。
例如:

  • 序列 10101 是神奇数列。
  • 序列 1011 不是神奇数列。

现在,小F想知道在这个序列中,最长的「神奇数列」是哪一个。如果有多个神奇数列长度相同,输出最先出现的那个。

示例

样例1

输入:inp = "0101011101"
输出:'010101'

样例2

输入:inp = "1110101010000"
输出:'10101010'

样例3

输入:inp = "1010101010101010"
输出:'1010101010101010'

解题思路

要找到最长的神奇数列,需要对整个字符串进行逐步扫描,检查每个子序列是否符合条件,并记录最长的符合条件的子序列。

解题步骤

  1. 神奇数列的判定

    • 一个子序列是神奇数列需要满足:
      1. 至少长度为 3。
      2. 每两个相邻字符交替,即 101010 的形式。
    • 对此可以实现一个函数 is_magic
  2. 枚举子序列

    • 使用双重循环,枚举所有可能的子序列。
    • 对每个子序列调用 is_magic 函数进行验证。
    • 如果该子序列为神奇数列且长度大于当前记录的最大长度,则更新结果。
  3. 时间优化

    • 虽然双层循环遍历时间复杂度为 (O(n^2)),但子序列验证成本较低,直接比较字符,保证每次验证快速结束。

代码实现

def solution(inp):
    # 检查是否是神奇数列
    def is_magic(seq):
        if len(seq) < 3:
            return False
        for i in range(len(seq) - 1):
            if seq[i] == seq[i + 1]:  # 相邻字符不能相等
                return False
        return True

    # 初始化变量
    n = len(inp)
    max_len = 0
    result = ""

    # 枚举所有可能的子序列
    for i in range(n):
        for j in range(i + 3, n + 1):  # 至少长度为3
            sub_seq = inp[i:j]
            if is_magic(sub_seq) and len(sub_seq) > max_len:
                max_len = len(sub_seq)
                result = sub_seq

    return result


if __name__ == "__main__":
    # 测试用例
    print(solution("0101011101") == "010101")  # True
    print(solution("1110101010000") == "10101010")  # True
    print(solution("1010101010101010") == "1010101010101010")  # True

MarsCode发挥的作用

  1. 函数分离

    • is_magic 函数封装了神奇数列的验证逻辑,将功能模块化,使代码更清晰易懂。
  2. 双层循环的精确范围控制

    • 外层循环从头到尾遍历序列,内层循环从起点开始寻找符合条件的子序列,枚举范围优化为从长度至少为 3 开始。
  3. 判定和更新逻辑的优化

    • 在判断当前子序列是否为神奇数列后,直接通过比较长度更新结果,保证结果始终正确。
  4. 清晰的边界条件

    • 若序列长度不足 3,直接跳过,避免不必要的运算。

总结

本题重点在于:

  1. 分离判断逻辑与主流程:通过 is_magic 函数实现神奇数列的判定,保持主循环逻辑简洁。
  2. 暴力解法的合理优化:通过设置子序列长度下限和逐步更新最长长度,避免不必要的冗余计算。
  3. 边界条件的处理:保证所有情况下均能返回正确结果。

代码设计合理,易读性强,适用于小规模数据场景((n \leq 10^4))。