题目解析与学习总结:找出最长的神奇数列 | 豆包MarsCode AI刷题

91 阅读3分钟

问题描述

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

 

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

解题思路

1.明确神奇数列的特点:

数列中的每个字符都与相邻字符交替,即 0 和 1 交替出现;

子串的最短长度为 6(包括至少三个交替单位 01 或 10)。

2.遍历字符串:

从每个字符开始尝试寻找交替子串。

如果当前字符与上一个字符不同,则继续扩展交替子串;

如果当前字符与上一个字符相同,则中断交替子串的查找。

3.记录最长交替子串:

每次中断时,检查当前交替子串是否符合神奇数列的条件(长度 ≥ 6 且交替次数 ≥ 3)。

如果当前子串比已记录的最长子串更长,则更新记录。

注意边界条件4.

如果整个字符串都交替,则在遍历结束时检查当前交替子串是否为最长子串。

代码实现:

 public class Main {
 public static String solution(String inp) {
    int maxLen = 0; // 当前找到的最长神奇数列的长度
    int startIndex = -1; // 记录最长神奇数列的起始位置
    int n = inp.length(); // 输入字符串的长度

    // 遍历字符串中的每个字符,尝试以其为起点寻找神奇数列
    for (int i = 0; i < n; i++) {
        int currentLen = 1; // 当前神奇数列的长度
        int runs = 1; // 当前神奇数列的交替次数
        char prevChar = inp.charAt(i); // 当前字符
        int j = i + 1;

        // 检查从当前位置开始的子串是否交替
        while (j < n) {
            if (inp.charAt(j) != prevChar) { 
                // 如果当前字符与前一个字符不同,则继续扩展神奇数列
                runs++; 
                currentLen++;
                prevChar = inp.charAt(j);
                j++;
            } else {
                // 如果当前字符与前一个字符相同,则中断神奇数列
                break;
            }
        }

        // 如果找到的交替次数 >= 3 且长度符合条件
        if (runs >= 3) {
            // 更新最长神奇数列的记录
            if (currentLen > maxLen || (currentLen == maxLen && i < startIndex)) {
                maxLen = currentLen;
                startIndex = i;
            }
        }
    }

    // 根据找到的起始位置和长度返回最长神奇数列
    if (startIndex != -1) {
        return inp.substring(startIndex, startIndex + maxLen);
    } else {
        return ""; // 如果没有找到符合条件的神奇数列,返回空字符串
    }
}

public static void main(String[] args) {
    System.out.println(solution("0101011101").equals("010101")); // 输出: "010101"
    System.out.println(solution("1110101010000").equals("10101010")); // 输出: "10101010"
    System.out.println(solution("1010101010101010").equals("1010101010101010")); // 输出: "1010101010101010"
    System.out.println(solution("0000110000110100000").equals("1010")); // 输出: "1010"
    System.out.println(solution("1011").equals("")); // 输出: "" (没有符合条件的神奇数列)
}

}

个人思考与分析

1.算法的关键点:

核心在于如何动态判断子串的交替性以及长度是否符合要求;

使用 runs 变量统计交替次数,保证逻辑清晰。

2.适用场景:

该算法适用于所有「连续模式匹配」的问题,如寻找最长交替数列、连续递增数列等。

3.个人收获:

通过本题学习了如何动态维护子串属性(长度、交替次数等)。

体会了在多条件问题中优先级的处理方法(长度优先、位置优先)。