python新手刷题之:时尚圈的衣着稳定性问题 | 豆包MarsCode AI刷题

185 阅读4分钟

问题描述:

小U在时尚圈组织了一场“校服日”活动,有n名学生围成一圈参加活动。每位学生都穿着白色或黑色的校服,白色用0表示,黑色用1表示。每一天,如果某个学生发现自己和相邻的两位学生穿着相同颜色的校服,那么他会在第二天更换成另一种颜色的校服;否则,他会保持不变。你的任务是帮助小U判断,在第几天学生们的穿着会达到稳定状态--即某天后,所有学生的穿着不再发生任何变化。同时,你还需要计算在稳定后有多少学生的校服颜色与其相邻的同学不同,这些学生被称为“时尚达人”最终你需要返回一个包含两个元素的数组:

第一个数字表示稳定下来的天数。如果永远无法稳定,则输出-1。

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

测试样例:

输入:n = 4, data = ["0000"] 输出:[-1, -1]
输入:n = 4, data = ["1110"] 输出:[2, 4]
输入:n = 6, data = ["010101"] 输出:[1, 6]

解题过程:

看完题目的当下其实脑海中一点思路也没有,似乎要考虑到的事情很多,相邻元素是否相同,元素值的改变,需要反复检验是否满足要求,而且还需要判断什么时候满足要求,一时间不知从何下手。但已经知道需要考虑的点了,那将它们逐个击破就好了。首先,关于判断相邻元素是否相同,这里需要用到循环遍历,每次都要判断左右两个元素。值得注意的是,题干中有提到所有元素是围成环形,那检查第0号元素时也需要考虑到第n-1号元素,同理,检查第n-1号元素时也要考虑第0号元素。为了防止索引出界,我采用了取模的方式获取左右两边元素的索引:

left = (i - 1) % n
right = (i + 1) % n

其次,关于元素值的改变,只要被检测元素与相邻元素都相同,那就改变它的元素就好了,反之则保留。但由于需要反复检验,不能直接在原数据上动工,所以我选择将改变的值存入新的列表new_data中。循环检验的过程就用while循环,循环条件设置了一个参数day,初始值为1,每经过一次循环就+1,来模拟天数的增长。最后,关于如何结束循环的条件,只要判断new_data和data是否相同即可,因为不同就代表所有元素都满足了题干中的要求,都没有做出变化,那这时就可以结束循环了。

另外,题目中还有一个要求,需要给出最终的“时尚达人”数量。这一步其实和判断相邻元素一样,只是需要修改一下循环条件,改成与相邻元素都不相同时进入循环体,循环体内就是计数+1。

思路大致清楚了,最终完成的代码如下所示:

def solution(n, data):
    # Edit your code here
    if n == 1:
        return [1, 1]
    if n == 2:
        return [1, 2] if data[0] != data[1] else [-1, -1]
    if '0' not in data or '1' not in data:
        return [-1, -1]

    # 模拟每天的情况
    day = 1
    while day:
        new_data = []
        for i in range(n):
            left = (i -1 + n) % n
            right = (i + 1 + n) % n
            if data[left] == data[i] and data[right] == data[i]:
                new_data.append('1' if data[i] == '0' else '0')
            else:
                new_data.append(data[i])
        new_data = ''.join(new_data)
        if new_data == data:
            break
        data = new_data
        day += 1

    # 计算“时尚达人”数量
    count = 0
    for i in range(n):
        left = (i - 1) % n
        right = (i + 1) % n
        if data[left] != data[i] and data[right] != data[i]:
            count += 1

    return [day, count]

这段代码实际上分了三个部分。第一个部分是针对特殊问题给出的特殊解,只要根据题干写好判断语句的条件即可,这样也能节省程序运行的时间。第二部分是模拟每天的情况,模拟学生的服装更替,直到满足要求。这一部分中用到了join函数,这是因为data和new_data存储字符串的形式不太一样,data中保存的是一整个字符串,而new_data是单个字符组成的字符串,以样例2为例:

使用join函数前:new_data: ['1', '1', '1', '0']
使用join函数后:new_data: '1110'

所以要用到join函数将元素合并为一个整体,否则后续的new_data == data的判断语句永远都是判断为False。最后的第三部分就是计数,代码实际来源于第二部分,修改了一些部分。最后返回天数day和人数count。提交代码,完成解题。