问题描述
小明是一个中学生,今天他刚刚学习了数列。他在纸上写了一个长度为 n 的正整数序列,a0,a1,…,an−1a0,a1,…,an−1。这个数列里面只有 1 和 0,我们将 1 和 0 没有重复跟随并且至少由 3 个数组成的数列的数列称之为「神奇数列」。比如 10101 是一个神奇数列,1011 不是一个神奇数列。他想知道这个序列里面最长的「神奇数列」是哪个,你可以帮帮他吗?
输入格式
- 一行连续的数
s,只有0和1
输出格式
- 一行数
输入样例
0101011101
输出样例
010101
数据范围
- 1<s.length≤5×1041<s.length≤5×104
问题分析
解题思路
-
遍历字符串:
- 需要遍历字符串
s,检查每个子串是否符合「神奇数列」的定义。
- 需要遍历字符串
-
检查子串:
-
对于每个子串,检查其是否满足以下条件:
- 长度至少为 3。
- 1 和 0 没有重复跟随。
-
-
记录最长的子串:
- 在遍历过程中,记录符合条件的最长子串。
算法步骤
-
初始化:
- 初始化一个空字符串
longest_magic_sequence,用于存储最长的「神奇数列」。
- 初始化一个空字符串
-
遍历字符串:
-
使用两个嵌套的循环遍历所有可能的子串:
- 外层循环控制子串的起始位置
start。 - 内层循环控制子串的结束位置
end,从start + 2开始,确保子串长度至少为 3。
- 外层循环控制子串的起始位置
-
-
检查子串:
- 对于每个子串,调用一个函数
isMagicSequence检查其是否符合「神奇数列」的定义。
- 对于每个子串,调用一个函数
-
更新最长子串:
- 如果子串符合条件且长度大于当前最长子串,则更新
longest_magic_sequence。
- 如果子串符合条件且长度大于当前最长子串,则更新
-
返回结果:
- 返回最长的「神奇数列」。
代码基本原理与步骤
1. isMagicSequence 函数
-
功能:检查给定的子串是否符合「神奇数列」的定义。
-
步骤:
- 遍历子串,从第二个字符开始(索引为1)。
- 检查当前字符是否与前一个字符相同。
- 如果发现连续的1或0,返回
false。 - 如果遍历完子串没有发现连续的1或0,返回
true。
bool isMagicSequence(const string& sub) {
// 检查子串是否符合「神奇数列」的定义
// 检查是否有连续的1或0
for (size_t i = 1; i < sub.length(); ++i) {
if (sub[i] == sub[i - 1]) {
return false;
}
}
return true;
}
2. solution 函数
-
功能:找到输入字符串中最长的「神奇数列」。
-
步骤:
-
初始化一个空字符串
longest_magic_sequence,用于存储最长的「神奇数列」。 -
获取输入字符串的长度
n。 -
使用两个嵌套的
for循环遍历所有可能的子串:- 外层循环控制子串的起始位置
start。 - 内层循环控制子串的结束位置
end,从start + 2开始,确保子串长度至少为3。
- 外层循环控制子串的起始位置
-
对于每个子串
sub,调用isMagicSequence函数检查其是否符合「神奇数列」的定义。 -
如果子串符合条件且长度大于当前最长子串,则更新
longest_magic_sequence。 -
返回最长的「神奇数列」。
-
string solution(const string& inp) {
string longest_magic_sequence = "";
int n = inp.length();
for (int start = 0; start < n; ++start) {
for (int end = start + 2; end < n; ++end) {
string sub = inp.substr(start, end - start + 1);
// 检查子串是否符合「神奇数列」的定义
// 如果符合,并且长度大于当前最长子串,则更新最长子串
if (isMagicSequence(sub) && sub.length() > longest_magic_sequence.length()) {
longest_magic_sequence = sub;
}
}
}
return longest_magic_sequence;
}