问题描述
小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]