题目描述
如果数组的每一对相邻元素都是两个奇偶性不同的数字,则该数组被认为是一个 特殊数组。
周洋哥有一个整数数组 nums
和一个二维整数矩阵 queries
,对于 queries[i] = [from_i, to_i]
,请你帮助周洋哥检查子数组 nums[from_i..to_i]
是不是一个 特殊数组。
返回布尔数组 answer
,如果 nums[from_i..to_i]
是特殊数组,则 answer[i]
为 true
,否则,answer[i]
为 false
。
样例
输入:nums = [3,4,1,2,6], queries = [[0,4]]
输出:[false]
解释:
子数组是 [3,4,1,2,6]。2 和 6 都是偶数。
输入:nums = [4,3,1,6], queries = [[0,2],[2,3]]
输出:[false,true]
解释:
1. 子数组是 [4,3,1]。3 和 1 都是奇数。因此这个查询的答案是 false。
2. 子数组是 [1,6]。只有一对:(1,6),且包含了奇偶性不同的数字。
因此这个查询的答案是 true。
限制
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5
1 <= queries.length <= 10^5
queries[i].length == 2
0 <= queries[i][0] <= queries[i][1] <= nums.length - 1
算法
(预处理,前缀和) $O(n + m)$
- 预处理原数组,如果发现 $nums(i)$ 与 $num(i + 1)$ 的奇偶性相同,则令 $nums(i) = 1$;否则令 $nums(i) = 0$。
- 求预处理后 $nums$ 数组的前缀和。
- 对于每一个询问 $from$ 和 $to$,求 $[from, to-1]$ 区间内的和是否为 $0$。如果为 $0$ 则说明这个查询的答案是 $true$;否则,为 $false$。
- 注意边界处理。
时间复杂度
- 预处理数组的时间复杂度为 $O(n)$。
- 对于每个询问,只需要常数的时间就可以得到答案。
- 故总时间复杂度为 $O(n + m)$。
空间复杂度
- 需要 $O(m)$ 的额外空间存储答案。
C++ 代码
class Solution {
public:
vector<bool> isArraySpecial(vector<int>& nums, vector<vector<int>>& queries) {
const int n = nums.size();
const int m = queries.size();
for (int i = 0; i < n - 1; i++)
nums[i] = ((nums[i] ^ nums[i + 1]) & 1) ^ 1;
for (int i = 1; i < n - 1; i++)
nums[i] += nums[i - 1];
vector<bool> ans(m);
for (int i = 0; i < m; i++) {
int l = queries[i][0], r = queries[i][1];
ans[i] = r ? (nums[r - 1] - (l ? nums[l - 1] : 0) == 0) : true;
}
return ans;
}
};