找出最长的神奇数列|青训营笔记

111 阅读4分钟

问题描述

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

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

题目分析:

神奇数列定义:

1、数列中“1”和“0”交替出现(开头可能是“0”或“1”,结尾也可能是“0”或“1”)

2、至少由3个连续的“0”和“1”组成的数列

我们需要找到最长的神奇数列,如果存在多个相同最长的数列,要找到最先出现的一个

思路

举例:inp = "0101011101"

我们可以设置一个变量flag来进行分析

inp[0]="0", flag="1"

inp[1]=flag="1",说明这两个数据是连续的“0”,“1”交替出现形成的,此时flag赋予新的值,flag="0"

inp[2]=flag="0",说明这三个数据都是连续的“0”,“1”交替出现形成的,此时flag赋予新的值,flag="1"

inp[3]=flag="1",说明这四个数据都是连续的“0”,“1”交替出现形成的,此时flag赋予新的值,flag="0"

inp[4]=flag="0",说明这五个数据都是连续的“0”,“1”交替出现形成的,此时flag赋予新的值,flag="1"

inp[5]=flag="1",说明这六个数据都是连续的“0”,“1”交替出现形成的,此时flag赋予新的值,flag="0"

inp[6]="1"!=flag,此时说明第七个数据无法与前面六个数据形成神奇数列

此时我们重新从第七个数据开始往后分析

inp[6]="1",flag="0"

inp[7]="1"!=flag,说明第七个数据和第八个数据不是连续的“0”,“1”交替出现形成的

此时我们重新从第八个数据开始往后分析

inp[7]="1",flag="0"

inp[8]=flag="0",说明这两个数据是连续的“0”,“1”交替出现形成的,此时flag赋予新的值,flag="1"

inp[9]=flag="1",说明这三个数据是连续的“0”,“1”交替出现形成的,此时flag赋予新的值,flag="0"

此时所有数据我们都已经分析完成,得出了两个神奇数列010101101

明显可知道题目所要求的最长神奇数列为010101

代码

分析完思路后,将思路中的思想用代码实现

def solution(inp):
    leng=len(inp)  #字符串长度,为了遍历数组
    n=0            #统计神奇数列长度
    max=0          #记录最长的神奇数列长度
    ans=[]         #创造一个列表记录找到的神奇数列
    i=0            #外循环的初值
    while(i<leng):
        dp=inp[i]  #dp(即思路中的flag)
        for j in range(i,leng): 
            if dp==inp[j] and dp=="0":    
                n+=1
                dp="1"
            elif dp==inp[j] and dp=="1":
                n+=1
                dp="0"
            elif dp!=inp[j]:     #发现inp[j]无法与前面数据组成神奇数列,从这个数据开始重新判断
                if n==max :
                    end=j        #记录此时的j
                i=j-1            #将i变化到j这个数据(因为后面有i+=1,所以这里是i-1)
                n=0              #长度清零
                break
            if n>max:            #找最大长度
                max=n
            if j==leng-1 and n==max:  #如果从i到leng-1都是神奇数列,而且还是最长的神奇数列
                end=j+1         #记录此时的j
                i=j             #结束外层循环
                n=0
                break
            elif j==leng-1 and n<max:  #如果从i到leng-1是神奇数列,但比最长神奇数列短,不需要记录
                n=0
                i=j
                break
        ans_part=[]         #记录单个神奇数列
        for m in range(end-max,end):
            ans_part.append(inp[m])
        ans.append(ans_part)
        i+=1               #让外层循环可以进行
    for i in ans:
        if len(i)==max and len(i)>=3:
            return "".join(i)   #将找到符合要求的神奇数列以字符串形式输出出来
    return ""   #如果没有满足要求的神奇数列,返回“”