96时尚圈的衣着稳定性问题 | 豆包MarsCode AI刷题

68 阅读4分钟

问题描述

小U在时尚圈组织了一场“校服日”活动,有 n 名学生围成一圈参加活动。每位学生都穿着白色或黑色的校服,白色用 0 表示,黑色用 1 表示。每一天,如果某个学生发现自己和相邻的两位学生穿着相同颜色的校服,那么他会在第二天更换成另一种颜色的校服;否则,他会保持不变。

你的任务是帮助小U判断,在第几天学生们的穿着会达到稳定状态——即某一天后,所有学生的穿着不再发生任何变化。同时,你还需要计算在稳定后,有多少学生的校服颜色与其相邻的同学不同,这些学生被称为“时尚达人”。

最终你需要返回一个包含两个元素的数组:

  • 第一个数字表示稳定下来的天数。如果永远无法稳定,则输出 -1
  • 第二个数字表示稳定后成为“时尚达人”的学生人数。如果永远无法稳定,则输出 -1

测试样例1:

输入:`n = 4 ,data = "0000"`  
输出:`[-1, -1]`
解释:初始状态下每个学生都和左右相邻同学的校服颜色都不一样,因此每天每个同学都会更换校服颜色,形成了死循环,因此永远无法稳定下来。

测试样例2:

输入:`n = 4 ,data = "1110"`  
输出:`[2, 4]`
解释:第一天状态为初始状态“1110”,第二天状态为“1010”,第三天发现没有可改变的地方即为在第2天达到稳定。

问题分析

首先可以确定的是有两重循环,外层循环判断是否达到稳定状态,如果没有,则进行内层循环,遍历每个同学并视情况改变他的校服颜色。另外由于要对data进行修改,而字符串是不可以通过s[i]=value这种方式修改值的,因此将字符串改为整数列表比较方便:data = list(map(int, list(data)))

1.外层循环结束的条件

题目要求得到第一个稳定下来的天数,即这一天之后的学生校服颜色均不会再发生改变了,因此我们可以维护一个last变量,保存上一天学生的校服颜色情况,如果进行一次完成内循环后发现当前的data==last,说明在前一天已达到稳定,直接跳出循环,返回天数。如果data!=last,说明还未稳定,day+=1后进行下一次外层循环。

    day = 1
    last = copy.copy(data)
    while 1:
        index = []    #存储需要改变校服颜色的学生下标
        '''
        遍历每个学生检查是否需要改变校服颜色,是则将下标加入index,然后遍历index改变学生的校服颜色
        '''
        
        if data == last:
            break
        
        day += 1
        last = copy.copy(data)

那么这个地方为什么不直接遍历一次data,直接修改学生校服颜色呢?而是要先把需要修改校服颜色的下标存储下来,再遍历下标来修改?原因是如果检查一个修改一个,前面修改的结果会影响到后面的修改,我们要保证每一轮的修改都是在同一个原始的data上修改的,因此要先保持data不变。

2.内层循环

内层循环就很简单了,直接将data遍历一次即可,唯一需要注意的是2个边界,由于学生们围成了一圈,因此这个data实际上是一个环形列表,因此检查需要分为三种情况:

  • i=0时,检查data[0]、data[1]、data[n-1]三者的相等情况
  • i=n-1时,检查data[n-2]、data[n-1]、data[0]的相等情况
  • 0<i<n-1时,检查data[i-1]、data[i]、data[i+1]的相等情况

参考代码

def solution(n, data):
    # Edit your code here
    data = list(map(int, list(data)))
    all_the_same = True
    for num in data:
        if num != data[0]:
            all_the_same = False
    if all_the_same:
        return [-1,-1]
    
    day = 1
    last = copy.copy(data)
    while 1:
        index = []
        if data[0] == data[n-1] and data[0] == data[1]:
            index.append(0)
        for i in range(1, n-1):
            if data[i] == data[i-1] and data[i] == data[i+1]:
                index.append(i)
        if data[n-1] == data[n-2] and data[n-1] == data[0]:
            index.append(n-1)
        
        for i in index:
            if data[i] == 0:
                data[i] = 1
            else:
                data[i] = 0
        
        if data == last:
            break
        
        day += 1
        last = copy.copy(data)

    ans = 0
    for i in range(n):
        if i == 0:
            if data[0] != data[n-1] and data[0] != data[1]:
                ans += 1
        elif i == n-1:
            if data[n-1] != data[n-2] and data[n-1] != data[0]:
                ans += 1
        else:
            if data[i] != data[i-1] and data[i] != data[i+1]:
                ans += 1
    
    return [day, ans]