每日一题:时尚圈的衣着稳定问题 | 豆包MarsCode AI 刷题
问题描述
小U在时尚圈组织了一场“校服日”活动,有 n 名学生围成一圈参加活动。每位学生都穿着白色或黑色的校服,白色用 0 表示,黑色用 1 表示。每一天,如果某个学生发现自己和相邻的两位学生穿着相同颜色的校服,那么他会在第二天更换成另一种颜色的校服;否则,他会保持不变。
你的任务是帮助小U判断,在第几天学生们的穿着会达到稳定状态——即某一天后,所有学生的穿着不再发生任何变化。同时,你还需要计算在稳定后,有多少学生的校服颜色与其相邻的同学不同,这些学生被称为“时尚达人”。
最终你需要返回一个包含两个元素的数组:
- 第一个数字表示稳定下来的天数。如果永远无法稳定,则输出
-1。 - 第二个数字表示稳定后成为“时尚达人”的学生人数。如果永远无法稳定,则输出
-1。
测试样例
样例1:
输入:
n = 4 ,data = "0000"输出:[-1, -1]
样例2:
输入:
n = 4 ,data = "1110"输出:[2, 4]
样例3:
输入:
n = 6 ,data = "010101"输出:[1, 6]
问题分析
1. 初始化
current_state = list(data)
days = 0
max_days = 100 # 限制最大天数,防止无限循环
current_state:将传入的字符串data转换成列表形式,便于后续修改。days:用来记录模拟的天数。max_days:设定一个最大天数的限制,以防止无限循环。如果经过max_days次循环仍然没有稳定,则返回[-1, -1]。
2. 模拟每一天的变化
while days < max_days:
new_state = current_state.copy()
change_occurred = False
- 使用
while循环模拟每一天的变化。days < max_days确保我们不会无限循环。 new_state:每天的变化后的校服状态,初始化为当前状态的副本。这样可以避免直接在原始current_state上修改,造成修改影响下一次的计算。change_occurred:标志变量,表示当天是否有任何学生改变了校服。如果当天没有任何变化,则说明已经达到了稳定状态。
3. 逐个学生判断是否更换校服
for i in range(n):
left = current_state[(i - 1) % n] # 左边的学生
right = current_state[(i + 1) % n] # 右边的学生
if current_state[i] == left and current_state[i] == right:
new_state[i] = '1' if current_state[i] == '0' else '0'
change_occurred = True
for i in range(n):遍历每个学生。left和right分别表示该学生左边和右边的学生。通过使用(i - 1) % n和(i + 1) % n来处理圆圈的情况,确保循环的学生能够与第一个和最后一个学生相邻。- 判断
current_state[i] == left and current_state[i] == right:如果左右邻居的校服颜色相同,那么该学生会更换校服。更换后的颜色是'1'或'0',取反原来的颜色。 - 如果有更换,设置
change_occurred = True,表示当天有变化。
4. 判断是否达到稳定
days += 1
current_state = new_state
if not change_occurred:
break # 没有变化,达到稳定状态
days += 1:每天增加 1。current_state = new_state:将当天的状态更新为新的状态。- 如果当天没有任何变化(即
change_occurred为False),则说明已经达到了稳定状态,跳出循环。
5. 判断是否达到最大天数
if days == max_days:
return [-1, -1] # 永远无法稳定
- 如果循环超过了最大天数
max_days仍然没有稳定状态,返回[-1, -1],表示无法稳定。
6. 计算时尚达人
fashionistas = 0
for i in range(n):
if current_state[i] != current_state[(i - 1) % n] and current_state[i] != current_state[(i + 1) % n]:
fashionistas += 1
-
fashionistas变量用来记录时尚达人的数量。 -
遍历每个学生,检查学生的穿着是否与左右邻居不同。如果不同,则该学生是时尚达人。
- 判断条件
current_state[i] != current_state[(i - 1) % n] and current_state[i] != current_state[(i + 1) % n]。
- 判断条件
7. 返回结果
return [days, fashionistas]
-
返回一个列表,包含两个元素:
days:稳定所需的天数。fashionistas:稳定状态下,时尚达人的数量。
代码总结
- 模拟变化:每一天更新学生的穿着状态,直到没有学生再变化或超过最大天数限制。
- 稳定判断:通过
change_occurred判断是否发生了变化,若没有变化则说明已经稳定。 - 时尚达人计算:在稳定状态下,遍历每个学生,统计那些穿着与邻居不同的学生。
时间复杂度分析
- 每一天需要遍历
n个学生,判断他们是否更换校服。 - 最多循环
max_days次,最终时间复杂度是 O(n * max_days),其中max_days默认设置为 100。 - 对于大多数情况,
max_days不会用尽,因此通常情况是 O(n)。
完整代码
def solution(n, data):
current_state = list(data)
days = 0
max_days = 100 # 限制最大天数,防止无限循环
while days < max_days:
new_state = current_state.copy()
change_occurred = False
for i in range(n):
left = current_state[(i - 1) % n] # 左边的学生
right = current_state[(i + 1) % n] # 右边的学生
if current_state[i] == left and current_state[i] == right:
new_state[i] = '1' if current_state[i] == '0' else '0'
change_occurred = True
days += 1
current_state = new_state
if not change_occurred:
break # 没有变化,达到稳定状态
if days == max_days:
return [-1, -1] # 永远无法稳定
# 计算时尚达人
fashionistas = 0
for i in range(n):
if current_state[i] != current_state[(i - 1) % n] and current_state[i] != current_state[(i + 1) % n]:
fashionistas += 1
return [days, fashionistas]
# 测试用例
if __name__ == "__main__":
print(solution(4, "0000") == [-1, -1])
print(solution(4, "1110") == [2, 4])
print(solution(6, "010101") == [1, 6])