题目描述
有一个人8间的牢房,用一个含8个元素数组nums表示,元素值为1表示占用,元素值为0表示未占用,现给定如下变化规则:
- 第 k 天,索引为 i 的牢房 ,num[i]相邻房间如果前一天(k - 1 天)都未占用或都占用,则num[i]置1表示占用,否则置为0;
- 对于牢房开始和末尾两个房间不存在两个相邻的牢房,
返回经过n天后牢房占用的状态
注:1 <= n <= 1e5,第一个牢房和最后一个牢房不存在相邻的两个房间
示例1:
输入:nums = [0, 1, 0, 1, 1, 0, 0, 1], days = 4;
输出:nums = [0, 0, 0, 0, 0, 1, 0, 0]
解释:
第一天 nums = [0, 1, 1, 0, 0, 0, 0, 0]
第二天 nums = [0, 0, 0, 0, 1, 1, 1, 0]
第三天 nums = [0, 1, 1, 0, 0, 1, 0, 0]
第四天 nums = [0, 0, 0, 0, 0, 1, 0, 0]
解题思路
由于n可能比较大,暴力法直接遍历可能复杂度为O(nC), 其中n为天数,C为牢房间数,通过继续向后变化,发现到第十五天后开始重复状态,即可以优化算法,具体代码实现如下:
代码实现
#include <iostream>
#include <vector>
std::vector<int> updateArray(std::vector<int>& nums, int days) {
int n = nums.size();
std::vector<int> newNums(nums);
days %= 14;
while (days--) {
for (int i = 0; i < n; ++i) {
if (i == 0 || i == n - 1) {
newNums[i] = 0;
}
else {
newNums[i] = (nums[i - 1] == nums[i + 1]) ? 1 : 0;
}
}
nums = newNums;
}
return newNums;
}
int main() {
std::vector<int> nums = { 0, 1, 0, 1, 1, 0, 1, 0 };
for (int i = 0; i < 8; i++) {
std::cin >> nums[i];
}
int days;
std::cin >> days;
std::vector<int> result = updateArray(nums, days);
std::cout << "After " << days << " days, the updated array is: ";
for (int i = 0; i < result.size(); ++i) {
std::cout << result[i] << " ";
}
std::cout << std::endl;
system("pause");
return 0;
}