找出最长的神奇数列

151 阅读3分钟

问题描述

小F是一个好学的中学生,今天他学习了数列的概念。他在纸上写下了一个由 0 和 1 组成的正整数序列,长度为 n。这个序列中的 1 和 0 交替出现,且至少由 3 个连续的 0 和 1 组成的部分数列称为「神奇数列」。例如,10101 是一个神奇数列,而 1011 不是。现在,小F想知道在这个序列中,最长的「神奇数列」是哪一个。你能帮他找到吗?

如果有多个神奇数列,那么输出最先出现的一个。


测试样例

样例1:

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

样例2:

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

样例3:

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

题目解析

  1. 神奇数列定义

    • 序列必须交替出现 0 和 1(或 1 和 0)。
    • 序列长度必须至少为 3。
  2. 输出要求

    • 返回最长的神奇数列。
    • 如果存在多个满足条件的最长神奇数列,返回最先出现的那个。

解题思路

  • 遍历字符串

    • 从头到尾遍历,记录当前是否是一个交替序列。
    • 如果字符和上一个字符不同,就继续扩展当前交替序列。
    • 如果字符和上一个字符相同,说明当前交替序列结束,判断它是否满足条件(长度≥3)。
  • 记录最长序列

    • 用变量保存当前最长序列的起始索引和长度。
    • 遇到更长的交替序列时,更新这些变量。
  • 特殊情况

    • 如果字符串本身没有符合条件的交替序列,直接返回空字符串。
    • 最后需要检查是否遗漏了末尾的序列。

实现过程

  1. 初始化变量:

    • maxLength:记录最长神奇数列的长度。
    • startIndex:记录最长神奇数列的起始位置。
    • currentLength:当前正在检查的交替序列长度。
  2. 遍历字符串:

    • 比较当前字符和前一个字符,如果不同,则累加 currentLength
    • 如果相同,则表示交替中断,需要检查当前序列是否是神奇数列。
  3. 最终结果:

    • 如果 maxLength > 0,根据 startIndexmaxLength 截取子串。
    • 如果没有找到符合条件的序列,返回空字符串。

Java 代码实现

public class Main {
    public static String solution(String inp) {
        int n = inp.length();
        int maxLength = 0; // 记录最长神奇数列的长度
        int startIndex = -1; // 记录最长神奇数列的起始索引
        int currentLength = 1; // 当前连续交替序列的长度

        for (int i = 1; i < n; i++) {
            if (inp.charAt(i) != inp.charAt(i - 1)) {
                currentLength++; // 继续计算当前交替序列长度
            } else {
                // 如果遇到重复字符,检查当前交替序列是否符合要求
                if (currentLength >= 3) {
                    if (currentLength > maxLength) {
                        maxLength = currentLength;
                        startIndex = i - currentLength;
                    }
                }
                // 重置当前长度
                currentLength = 1;
            }
        }

        // 遍历完成后再检查最后一个序列
        if (currentLength >= 3) {
            if (currentLength > maxLength) {
                maxLength = currentLength;
                startIndex = n - currentLength;
            }
        }

        // 如果没有找到符合条件的子序列,返回空字符串
        if (startIndex == -1) {
            return "";
        }

        // 返回最长神奇数列
        return inp.substring(startIndex, startIndex + maxLength);
    }

    public static void main(String[] args) {
        // 测试用例
        System.out.println(solution("0101011101").equals("010101"));
        System.out.println(solution("1110101010000").equals("10101010"));
        System.out.println(solution("1010101010101010").equals("1010101010101010"));
    }
}

总结

  • 这道题考察了字符串的遍历和条件判断。
  • 重点在于如何动态维护交替序列的起始位置和长度。
  • 逻辑清晰,适合初学者理解,同时体现了边界条件的重要性。