这道题的题干要求和统计移除递增子数组的数目I的要求基本相似,不同点可能在于其对递增子数组的定义不同,所以我们这里只编写代码的实现逻辑。
代码编写思路:
这个程序的目的是找到数组中所有符合条件的“移除递增子数组”的数量。具体来说,如果移除一个子数组后,剩余的数组是严格递增的,那么这个子数组就符合条件。
定义一个函数incremovableSubarrayCount用于接收一个数组nums和数组的大小numsSize,返回符合条件的子数组的数量:
long long incremovableSubarrayCount(int* nums, int numsSize) {
long long ans = 0; // 结果变量,用于存储符合条件的子数组数量
int l = 0; // 左指针,初始化为0
第一步初步检查数组是否已经严格递增
while (l < numsSize - 1) {
if (nums[l] >= nums[l + 1]) {
break; // 如果找到不严格递增的地方,跳出循环
}
l++;
}
这里我们使用一个while循环从左向右遍历数组,检查是否存在不严格递增的地方。若nums[l] >= nums[l + 1]
,表示数组不严格递增,则跳出循环。
第二步处理整个数组严格递增的情况
if (l == numsSize - 1) {
return 1LL * numsSize * (numsSize + 1) / 2; // 计算所有子数组的数量并返回
}
若整个数组都是严格递增的,那么所有可能的子数组(包括单个元素的子数组和整个数组本身)都符合条件。所有子数组的数量可以通过公式numsSize*(bumsSize + 1)/ 2计算得到
第三步,初始化符合条件的子数组数量
ans += l + 2; // 初始化结果为 l + 2, 其中 +2 是因为空子数组和自身都符合条件
- 初始化符合条件的子数组数量,包含从左向右扫描过程中符合条件的部分。
l + 2
是因为从0
到l
之间的元素每个都可以单独移除,并且空子数组和整个数组本身都符合条件。
第四步, 从右向左扫描数组,使用双指针计算符合条件的子数组数量
for (int r = numsSize - 1; r > 0; r--) {
if (r < numsSize - 1 && nums[r] >= nums[r + 1]) {
break; // 如果发现右侧不严格递增的地方,跳出循环
}
while (l >= 0 && nums[l] >= nums[r]) {
l--; // 移动左指针直到找到比 nums[r] 小的元素
}
ans += l + 2; // 累加符合条件的子数组数量
}
return ans; // 返回最终的子数组数量
}
- 使用一个从右向左的
for
循环,右指针r
从数组的最后一个元素开始。 - 如果
nums[r] >= nums[r + 1]
,表示右侧不严格递增,则跳出循环。 - 通过
while
循环,移动左指针l
直到找到比nums[r]
小的元素。 - 累加符合条件的子数组数量
l + 2
到结果变量ans
中。