【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]
解释:
- 子数组是
[4,3,1]。3 和 1 都是奇数。因此这个查询的答案是 false。
- 子数组是
[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