题目描述
给你一个 二进制数组 nums 。
如果一个 子数组 中 不存在 两个 相邻 元素的值 相同 的情况,我们称这样的子数组为 交替子数组 。
返回数组 nums 中交替子数组的数量。
3101.交替子数组计数
测试案例及提示
示例 1:
输入: nums = [0,1,1,1]
输出: 5
解释:
以下子数组是交替子数组:[0] 、[1] 、[1] 、[1] 以及 [0,1] 。
示例 2:
输入: nums = [1,0,1,0]
输出: 10
解释:
数组的每个子数组都是交替子数组。可以统计在内的子数组共有 10 个。
提示:
1 <= nums.length <= 105
nums[i] 不是 0 就是 1 。
解题思路
对题目进行分析,交替子数组可以是只有一个元素,因此最少的个数就是数组长度,这是一点。另外一点可以发现某一个位置是否有交替子数组会与前一个位置的元素有关(相同则没有,不同则有),也就是说,后一个的状态与前一个有关。可以考虑使用动态规划来做。
Python:
class Solution:
def countAlternatingSubarrays(self, nums: List[int]) -> int:
cnt = len(nums)
dp = [0] * len(nums)
for i in range(1,len(nums)):
if nums[i] != nums[i - 1]:
dp[i] = dp[i - 1] + 1
cnt += dp[i]
return cnt
Java:
class Solution {
public long countAlternatingSubarrays(int[] nums) {
long cnt = nums.length; // 此处要注意cnt是累加值,可能会越int界
int[] dp = new int[nums.length]; // 不赋初值就是0
for (int i = 1; i < nums.length; i++) {
if (nums[i] != nums[i-1]) {
dp[i] = dp[i - 1] + 1;
cnt += dp[i];
}
}
return cnt;
}
}
一个可以优化的点:
在上面的代码中,我是使用了一个dp数组来保存每个元素的状态值,导致空间复杂度为O(n)。但这不是必要的,可以对dp数组进行优化,只使用一个值来记录当前的数组长度,这样可以降低空间复杂度至O(1)。
Python:
class Solution:
def countAlternatingSubarrays(self, nums: List[int]) -> int:
cnt = len(nums)
cur = 0
for i in range(1, len(nums)):
if nums[i] != nums[i - 1]:
cur += 1
cnt += cur
else:
cur = 0
return cnt
Java:
class Solution {
public long countAlternatingSubarrays(int[] nums) {
long cnt = nums.length;
int cur = 0;
for (int i = 1; i < nums.length; i++) {
if (nums[i] != nums[i-1]) {
cur++;
cnt += cur;
} else {
cur = 0;
}
}
return cnt;
}
}