Medium
题目描述
给你一个整数 n,表示一个长度为 n 的数组 colors,其中所有元素都被设置为 0,表示未着色。同时给你一个二维整数数组 queries,其中 queries[i] = [indexi, colori]。
对于第 i 个查询:
- 将
colors[indexi]设置为colori - 统计
colors中颜色相同的相邻对的数量(无论colori的值如何)
返回一个与 queries 长度相同的数组 answer,其中 answer[i] 是第 i 个查询的答案。
示例 1:
输入:n = 4, queries = [[0,2],[1,2],[3,1],[1,1],[2,1]]
输出:[0,1,1,0,2]
解释:
- 初始时 colors = [0,0,0,0],其中 0 表示数组中未着色的元素
- 第 1 次查询后 colors = [2,0,0,0]。颜色相同的相邻对数量为 0
- 第 2 次查询后 colors = [2,2,0,0]。颜色相同的相邻对数量为 1
- 第 3 次查询后 colors = [2,2,0,1]。颜色相同的相邻对数量为 1
- 第 4 次查询后 colors = [2,1,0,1]。颜色相同的相邻对数量为 0
- 第 5 次查询后 colors = [2,1,1,1]。颜色相同的相邻对数量为 2
示例 2:
输入:n = 1, queries = [[0,100000]]
输出:[0]
解释:
第 1 次查询后 colors = [100000]。颜色相同的相邻对数量为 0。
约束条件:
1 <= n <= 10^51 <= queries.length <= 10^5queries[i].length == 20 <= indexi <= n - 11 <= colori <= 10^5
解题思路
解题思路
这道题的关键在于理解每次修改颜色时,只会影响当前位置与其相邻位置的配对关系。我们不需要每次都重新计算整个数组的相邻相同对数量,而是可以通过增量更新来高效解决。
核心思路:
- 维护计数器:用一个变量
count记录当前相邻相同对的总数量 - 局部影响分析:每次修改位置
i的颜色时,只需要考虑位置i与其左邻居i-1和右邻居i+1的关系变化 - 增量更新:
- 修改前:如果
colors[i]与左邻居或右邻居颜色相同且都不为0,则count-- - 修改后:如果新的
colors[i]与左邻居或右邻居颜色相同,则count++
- 修改前:如果
实现要点:
- 初始化数组全为0(未着色状态)
- 对于每个查询,先减去原有的相邻相同对,然后更新颜色,最后加上新产生的相邻相同对
- 边界处理:注意数组边界,避免越界访问
- 0值处理:未着色的0不参与相邻相同对的计算
时间复杂度为 O(q),其中 q 是查询次数,空间复杂度为 O(n)。
代码实现
class Solution {
public:
vector<int> colorTheArray(int n, vector<vector<int>>& queries) {
vector<int> colors(n, 0);
vector<int> result;
int count = 0;
for (auto& query : queries) {
int index = query[0];
int newColor = query[1];
// 减去修改前的相邻相同对
if (index > 0 && colors[index] != 0 && colors[index] == colors[index-1]) {
count--;
}
if (index < n-1 && colors[index] != 0 && colors[index] == colors[index+1]) {
count--;
}
// 更新颜色
colors[index] = newColor;
// 加上修改后的相邻相同对
if (index > 0 && colors[index-1] != 0 && colors[index] == colors[index-1]) {
count++;
}
if (index < n-1 && colors[index+1] != 0 && colors[index] == colors[index+1]) {
count++;
}
result.push_back(count);
}
return result;
}
};
class Solution:
def colorTheArray(self, n: int, queries: List[List[int]]) -> List[int]:
colors = [0] * n
result = []
count = 0
for index, new_color in queries:
# 减去修改前的相邻相同对
if index > 0 and colors[index] != 0 and colors[index] == colors[index-1]:
count -= 1
if index < n-1 and colors[index] != 0 and colors[index] == colors[index+1]:
count -= 1
# 更新颜色
colors[index] = new_color
# 加上修改后的相邻相同对
if index > 0 and colors[index-1] != 0 and colors[index] == colors[index-1]:
count += 1
if index < n-1 and colors[index+1] != 0 and colors[index] == colors[index+1]:
count += 1
result.append(count)
return result
public class Solution {
public int[] ColorTheArray(int n, int[][] queries) {
int[] colors = new int[n];
int[] result = new int[queries.Length];
int count = 0;
for (int i = 0; i < queries.Length; i++) {
int index = queries[i][0];
int newColor = queries[i][1];
// 减去修改前的相邻相同对
if (index > 0 && colors[index] != 0 && colors[index] == colors[index-1]) {
count--;
}
if (index < n-1 && colors[index] != 0 && colors[index] == colors[index+1]) {
count--;
}
// 更新颜色
colors[index] = newColor;
// 加上修改后的相邻相同对
if (index > 0 && colors[index-1] != 0 && colors[index] == colors[index-1]) {
count++;
}
if (index < n-1 && colors[index+1] != 0 && colors[index] == colors[index+1]) {
count++;
}
result[i] = count;
}
return result;
}
}
var colorTheArray = function(n, queries) {
const colors = new Array(n).fill(0);
const result = [];
let count = 0;
for (const [index, newColor] of queries) {
// 减去修改前的相邻相同对
if (index > 0 && colors[index] !== 0 && colors[index]
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(q) | 其中 q 是查询次数,每次查询只需要常数时间处理 |
| 空间复杂度 | O(n) | 需要额外的数组存储颜色状态 |