计算长度为k的连续子数组的最大总和
1.滑动窗口算法概述
1.1 滑动窗口协议
滑动窗口协议(Sliding Window Protocol),该协议是 TCP协议 的一种应用,用于网络数据传输时的流量控制,以避免拥塞的发生。该协议允许发送方在停止并等待确认前发送多个数据分组。由于发送方不必每发一个分组就停下来等待确认。因此该协议可以加速数据的传输,提高网络吞吐量。
滑动窗口算法其实和这个是一样的,只是用的地方场景不一样,可以根据需要调整窗口的大小,有时也可以是固定窗口大小。
1.2 滑动窗口算法
滑动窗口算法(Sliding Window Algorithm)
Sliding window algorithm is used to perform required operation on specific window size of given large buffer or array.
滑动窗口算法是在给定特定窗口大小的数组或字符串上执行要求的操作。
This technique shows how a nested for loop in few problems can be converted to single for loop and hence reducing the time complexity.
该技术可以将一部分问题中的嵌套循环转变为一个单循环,因此它可以减少时间复杂度。
简而言之,滑动窗口算法在一个特定大小的字符串或数组上进行操作,而不在整个字符串和数组上操作,这样就降低了问题的复杂度,从而也达到降低了循环的嵌套深度。其实这里就可以看出来滑动窗口主要应用在数组和字符串上。
2. 计算长度为k的连续子数组的最大总和
/**
* 滑动窗口算法
*
* @author zrj
* @since 2021/11/15
**/
public class SlidingWindow {
/**
* For循环遍历
* 题目:给定一个整数数组,计算长度为k的连续子数组的最大总和。
* 时间复杂度:为O(k*n)
*/
@Test
public void maxSumFor() {
//定义长度
int k = 2;
//定义数组
int[] arr = {
100, 200, 300, 400};
int maxSum = 0;
for (int i = 0, size = arr.length; i < size - k + 1; i++) {
int currentSum = 0;
for (int j = 0; j < k; j++) {
currentSum += arr[i + j];
}
maxSum = Math.max(currentSum, maxSum);
}
System.out.println("【循环遍历】长度k连续数组最大总和:" + maxSum);
}
/**
* 滑动窗口算法
* 题目:给定一个整数数组,计算长度为k的连续子数组的最大总和。
* 时间复杂度:O(n)
*/
@Test
public void maxSumSliding() {
//定义长度
int k = 2;
//定义数组
int[] arr = {
100, 200, 300, 400};
int size = arr.length;
if (size < k) {
return;
}
int maxSum = 0;
//获取第一个滑动窗口值
for (int i = 0; i < k; i++) {
maxSum = maxSum + arr[i];
}
int sum = maxSum;
//循环sum是前两位的和,arr[i]是第三位的值,arr[i-k]第一位的值
//sum = sum + arr[i] - arr[i - k];求的是后两位的值,100+200+300-100
for (int i = k; i < size; i++) {
sum = sum + arr[i] - arr[i - k];
maxSum = Math.max(maxSum, sum);
}
System.out.println("【滑动窗口】长度k连续数组最大总和:" + maxSum);
}
}