解题思路
这是一个动态规划问题,需要同时维护正积和负积的长度:
- 使用两个变量:
- :以当前位置结尾的最长正积子数组长度
- :以当前位置结尾的最长负积子数组长度
- 对于每个新的数字 ,根据其正负性:
- 如果 : 加 , 如果存在则加
- 如果 :新 (如果 存在),新
- 如果 :重置 和 为
- 维护全局最大长度
代码
#include <iostream>
#include <vector>
using namespace std;
int getMaxLen(vector<int>& nums) {
int maxLen = 0;
int pos = 0; // 正积长度
int neg = 0; // 负积长度
for(int num : nums) {
if(num > 0) {
pos++;
neg = neg == 0 ? 0 : neg + 1;
}
else if(num < 0) {
int newPos = neg == 0 ? 0 : neg + 1;
int newNeg = pos + 1;
pos = newPos;
neg = newNeg;
}
else {
pos = 0;
neg = 0;
}
maxLen = max(maxLen, pos);
}
return maxLen;
}
int main() {
int n;
cin >> n;
vector<int> nums(n);
for(int i = 0; i < n; i++) {
cin >> nums[i];
}
cout << getMaxLen(nums) << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static int getMaxLen(int[] nums) {
int maxLen = 0;
int pos = 0; // 正积长度
int neg = 0; // 负积长度
for(int num : nums) {
if(num > 0) {
pos++;
neg = neg == 0 ? 0 : neg + 1;
}
else if(num < 0) {
int newPos = neg == 0 ? 0 : neg + 1;
int newNeg = pos + 1;
pos = newPos;
neg = newNeg;
}
else {
pos = 0;
neg = 0;
}
maxLen = Math.max(maxLen, pos);
}
return maxLen;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] nums = new int[n];
for(int i = 0; i < n; i++) {
nums[i] = sc.nextInt();
}
System.out.println(getMaxLen(nums));
sc.close();
}
}
def get_max_len(nums):
max_len = 0
pos = 0 # 正积长度
neg = 0 # 负积长度
for num in nums:
if num > 0:
pos += 1
neg = 0 if neg == 0 else neg + 1
elif num < 0:
new_pos = 0 if neg == 0 else neg + 1
new_neg = pos + 1
pos = new_pos
neg = new_neg
else:
pos = 0
neg = 0
max_len = max(max_len, pos)
return max_len
n = int(input())
nums = list(map(int, input().split()))
print(get_max_len(nums))
算法及复杂度
- 算法:动态规划
- 时间复杂度:,只需要遍历一次数组
- 空间复杂度:,只使用了常数个变量