前言
C++算法与数据结构
打开打包代码的方法兼述单元测试
LeetCode 1567. 乘积为正数的最长子数组长度
给你一个整数数组 nums ,请你求出乘积为正数的最长子数组的长度。
一个数组的子数组是由原数组中零个或者更多个连续数字组成的数组。
请你返回乘积为正数的最长子数组长度。
示例 1:
输入:nums = [1,-2,-3,4]
输出:4
解释:数组本身乘积就是正数,值为 24 。
示例 2:
输入:nums = [0,1,-2,-3,-4]
输出:3
解释:最长乘积为正数的子数组为 [1,-2,-3] ,乘积为 6 。
注意,我们不能把 0 也包括到子数组中,因为这样乘积为 0 ,不是正数。
示例 3:
输入:nums = [-1,-2,-3,0,1]
输出:2
解释:乘积为正数的最长子数组是 [-1,-2] 或者 [-2,-3] 。
提示:
1 <= nums.length <= 105
-109 <= nums[i] <= 109
子数组
子数组不能包括0,否则乘积是0,不是正整数。
如果没有0,nums[0…j]有偶数个负数,则以j结尾的最长子数组是[0…j];如果有奇数个负数,负数的最小下标是i1,则[i1+1…j]是以j结尾的最长子数组。
nums[0…j]中为0的最大下标是i3,如果没有则为-1。
如果nums[0…j]中的负数为偶数,i2=-1,否则i2=i1。
左闭右开空间(max(i2,i3),j]便是以j结尾的最长子数组。
注意: nums[i]为0后, lessCount = 0 要清零。
代码
核心代码
class Solution {
public:
int getMaxLen(vector<int>& nums) {
int ans = 0,lessCount=0,lessIndex=-1,zeroIndex=-1;
for (int i = 0; i < nums.size(); i++) {
if (nums[i] < 0) {
lessCount++;
if (1 == lessCount) {
lessIndex = i;
}
}
if (0 == nums[i]) {
zeroIndex = i;
lessCount = 0;
}
int i1 = zeroIndex;
if (lessCount & 1) {
i1 = max(i1, lessIndex);
}
ans = max(ans, i - i1);
}
return ans;
}
};
单元测试
vector<int> nums;
TEST_METHOD(TestMethod11)
{
nums = { 1, -2, -3, 4 };
auto res = Solution().getMaxLen(nums);
AssertEx(4, res);
}
TEST_METHOD(TestMethod12)
{
nums = { 0,1,-2,-3,-4 };
auto res = Solution().getMaxLen(nums);
AssertEx(3, res);
}
TEST_METHOD(TestMethod13)
{
nums = { -1,-2,-3,0,1 };
auto res = Solution().getMaxLen(nums);
AssertEx(2, res);
}
TEST_METHOD(TestMethod14)
{
nums = { 5,-20,-20,-39,-5,0,0,0,36,-32,0,-7,-10,-7,21,20,-12,-34,26,2 };
auto res = Solution().getMaxLen(nums);
AssertEx(8, res);
}