题目:
给定一个数组arr,该数组无序,但每个值均为正数,再给定一个正数k。求arr的所有子数组中所有元素相加和为k的最长子连续数组的长度
例如,arr = [1, 2, 1, 1, 1], k = 3
累加和为3的最长子数组为[1, 1, 1],所以结果返回3
[要求]
时间复杂度为O(n),空间复杂度为O(1)
没怎么动脑子,给出了一种解法,但是时间复杂度和空间复杂度应该都不对,
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int length = scanner.nextInt();
int sum = scanner.nextInt();
int[] arr = new int[length];
for (int i = 0; i < length; i++) {
arr[i] = scanner.nextInt();
}
System.out.println(theLongestSon(arr,sum));
}
public static int theLongestSon(int[] arr,int sum) {
int[] dp = new int[arr.length];
for (int i = 0; i < arr.length;i ++) {
int count = arr[i];
int j = i;
while (count < sum && j >= 1) {
j--;
count += arr[j];
}
if (count == sum) dp[i] = i-j+1;
else dp[i] = 0;
}
int max = dp[0];
for (int i = 0 ;i < arr.length;i++) {
if (max < dp[i]) {
max = dp[i];
}
}
return max;
}
}
采用滑动窗口的O(n)算法代码如下:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int length = scanner.nextInt();
int sum = scanner.nextInt();
int[] arr = new int[length];
for (int i = 0; i < length; i++) {
arr[i] = scanner.nextInt();
}
System.out.println(theLongestSon(arr,sum));
}
public static int theLongestSon(int[] arr,int sum) {
int q = 0;
int p = 0;
int count = 0 ;
int lengthMax = 0;
while (p < arr.length) {
if(count < sum) {
count = count + arr[p];
p = p+1;
} else if (count == sum){
lengthMax = p-q > lengthMax ? p-q : lengthMax;
count -= arr[q];
q = q+1;
} else {
count -= arr[q];
q = q+1;
}
}
return lengthMax;
}
}