3152.特殊数组 II

【LetMeFly】3152.特殊数组 II:前缀和 - 原地修改(大概可视为O(1)空间)

力扣题目链接:https://leetcode.cn/problems/special-array-ii/

如果数组的每一对相邻元素都是两个奇偶性不同的数字,则该数组被认为是一个 特殊数组

周洋哥有一个整数数组 nums 和一个二维整数矩阵 queries,对于 queries[i] = [fromi, toi],请你帮助周洋哥检查子数组 nums[fromi..toi] 是不是一个 特殊数组

返回布尔数组 answer,如果 nums[fromi..toi] 是特殊数组,则 answer[i]true ,否则,answer[i]false

 

示例 1:

输入:nums = [3,4,1,2,6], queries = [[0,4]]

输出:[false]

解释:

子数组是 [3,4,1,2,6]。2 和 6 都是偶数。

示例 2:

输入: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 <= 105
  • 1 <= nums[i] <= 105
  • 1 <= queries.length <= 105
  • queries[i].length == 2
  • 0 <= queries[i][0] <= queries[i][1] <= nums.length - 1

解题方法:前缀和

因为要多次查询a到b区间是否有奇偶性不同的元素,所以很自然地想到前缀和。

前缀和的原数组$origin$长这个样:

  • 如果$nums[i]$和$nums[i + 1]$奇偶性相同,则$origin[i] = 1$;
  • 否则$origin[i] = 0$。

前缀和数组$prefix$长这个样:

  • $prefix[i]$为$nums$前$i$个元素的和。(前$0$个元素的和记为$0$)

那么,如果$prefix[b] - prefix[a]$为$0$,则说明$nums[a]$到$nums[b]$奇偶性全相同;否则说明有奇偶性不相同的相邻元素的存在。

  • 时间复杂度$O(len(nums) + len(queries))$
  • 空间复杂度$O(1)$:可以做到原地修改数组,力扣算法的返回值又不计入算法的空间复杂度

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
vector<bool> isArraySpecial(vector<int>& nums, vector<vector<int>>& queries) {
int cnt = 0;
for (int i = 0; i < nums.size() - 1; i++) {
bool same = nums[i] % 2 == nums[i + 1] % 2;
nums[i] = cnt;
cnt += same;
}
nums.back() = cnt;
vector<bool> ans(queries.size());
for (int i = 0; i < queries.size(); i++) {
ans[i] = nums[queries[i][1]] == nums[queries[i][0]];
}
return ans;
}
};

Go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

func isArraySpecial(nums []int, queries [][]int) []bool {
cnt := 0
for i := 0; i < len(nums) - 1; i++ {
same := nums[i] % 2 == nums[i + 1] % 2
nums[i] = cnt
if same {
cnt++
}
}
nums[len(nums) - 1] = cnt
ans := make([]bool, len(queries))
for i, q := range queries {
ans[i] = nums[q[0]] == nums[q[1]]
}
return ans
}

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public boolean[] isArraySpecial(int[] nums, int[][] queries) {
int cnt = 0;
for (int i = 0; i < nums.length - 1; i++) {
boolean same = nums[i] % 2 == nums[i + 1] % 2;
nums[i] = cnt;
cnt += same ? 1 : 0;
}
nums[nums.length - 1] = cnt;
boolean[] ans = new boolean[queries.length];
for (int i = 0; i < queries.length; i++) {
ans[i] = nums[queries[i][0]] == nums[queries[i][1]];
}
return ans;
}
}

Python

1
2
3
4
5
6
7
8
9
10
11
from typing import List

class Solution:
def isArraySpecial(self, nums: List[int], queries: List[List[int]]) -> List[bool]:
cnt = 0
for i in range(len(nums) - 1):
same = nums[i] % 2 == nums[i + 1] % 2
nums[i] = cnt
cnt += same
nums[-1] = cnt
return [nums[a] == nums[b] for a, b in queries]

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

Tisfy:https://letmefly.blog.csdn.net/article/details/141203073


3152.特殊数组 II
https://blog.letmefly.xyz/2024/08/14/LeetCode 3152.特殊数组II/
作者
Tisfy
发布于
2024年8月14日
许可协议