问题描述:
在字节学校,有 n 个学生,他们相信自己是学校里最靓的仔,并希望自己的衣服与周围人的不同。学校的规定是,所有学生只能穿黑色或白色校服(0表示白色,1表示黑色)。学生们的座位是围成一个圈的,每天如果有一个学生发现自己左右邻居的衣服与自己一样,那么他就会在第二天换上另一种颜色的校服。如果两边的衣服与他不一样,他则继续穿原来的衣服。
问题要求:
- 计算学生们的衣服在第几天会稳定下来。稳定指的是在某一天,第二天的衣服与当天相同。
- 稳定下来后,计算“时尚达人”的数量。时尚达人定义为穿着与相邻同学都不一样的学生。
如果学生们永远不会稳定下来,则输出 -1 -1。
解题思路:
-
状态更新规则:
- 每个学生根据左右邻居的穿着决定是否更换衣服:如果左右两侧学生的衣服与自己相同,则第二天更换衣服;否则继续穿原来的衣服。
- 由于学生是围成圈的,所以首尾学生也是相邻的。
-
稳定条件:
- 如果某天的穿着与前一天相同,则说明穿着稳定下来。
- 如果天数超过
n仍然没有稳定,则说明无法稳定,返回-1 -1。
-
时尚达人判定:
- 稳定下来后,统计每个学生的左右邻居,若左右邻居穿着不同于自己,则该学生为时尚达人。
解题步骤:
- 模拟每一天的衣服变化,直到状态稳定。
- 统计总的稳定天数,并计算稳定后的时尚达人数量。
- 如果天数过多,返回
-1 -1表示无法稳定。
代码实现:
#include <iostream>
#include <vector>
#include <string>
std::vector<int> solution(int n, const std::string &data)
{ std::string current = data; std::string next = current; int days = 0; // 模拟每一天的变化
while (true) {
// 更新每个学生的穿着 next = current;
for (int i = 0; i < n; ++i) {
int left = (i == 0) ? current[n - 1] : current[i - 1];
// 左邻 int right = (i == n - 1) ? current[0] : current[i + 1];
// 右邻
if (left == current[i] && right == current[i]) {
next[i] = (current[i] == '0') ? '1' : '0'; // 更换衣服
}
} // 如果今天的穿着与昨天相同,说明稳定了 if (next == current) { break; } // 更新穿着 current = next; days++;
// 防止无限循环(如果天数太大)
if (days > n) { return {-1, -1}; } }
// 计算时尚达人数量
int fashionistaCount = 0;
for (int i = 0; i < n; ++i) {
int left = (i == 0) ? current[n - 1] : current[i - 1]; // 左邻 int right = (i == n - 1) ? current[0] : current[i + 1];
// 右邻
if (current[i] != left && current[i] != right)
{ fashionistaCount++; } }
return {days, fashionistaCount};
}
int main() {
// 测试用例 std::cout << (solution(4, "0000") == std::vector<int>{-1, -1}) << std::endl; std::cout << (solution(4, "1110") == std::vector<int>{2, 4}) << std::endl; return 0;
}
ai代码分析:
-
模拟过程:
- 使用
current字符串表示当前状态,next字符串表示下一天的状态。 - 每天根据左右邻居的穿着判断是否要更换衣服,并更新
next。 - 如果
current与next相同,表示穿着稳定,退出循环。
- 使用
-
稳定性判断:
- 若经过
n天还没有稳定,认为无法稳定,返回-1 -1。
- 若经过
-
时尚达人统计:
- 在稳定后遍历学生,如果其左右邻居与自己穿着不同,则该学生是时尚达人。
时间复杂度:
- 每天最多更新一次状态,更新过程是线性的,即
O(n)。 - 最多进行
n轮更新,因此时间复杂度为O(n^2),但是实际过程中状态变化较快,通常不会达到n轮。
空间复杂度:
- 使用了
O(n)的额外空间来存储当前和下一天的状态。
总结:
这道题通过模拟学生衣服变化的过程来解决问题,关键在于正确判断每个学生的左右邻居,并实现状态的更新。虽然最坏情况下时间复杂度为 O(n^2),但实际情况通常较为高效。