窗口滑动算法
原理我就不说了,直接上例子
例如我想找一个数组中的连续子数组的和等于9的最长长度,
{1, 2, 3, 4, 5}找连续的元素和是9的最长长度,结果应该是2+3+4=9
窗口算法:那么就是right先从第0元素走到第n个元素直到和大于9,那么这个时候就从左边开始第0个元素开始减去,直到不大于9,然后如果sum等于9则记录数值并和初始数值比较取大的(之后就是重复操作,直到最后一个元素了)
而传统操作是:从第一个元素开始,遍历到最后一个,获取中间的和=9的长度;从第二个元素开始,同样操作
比较:可以理解为就是省去了需要回撤重新开始的那段重复查询
代码
public class SlidingWindowExample {
public static int findMaxSubarrayLength(int[] nums, int target) {
int maxLength = 0; // 最长子数组的长度
int size = 0;
for (int i = 0; i < nums.length; i++) {
int sum = 0; // 当前子数组的和
for (int j = i; j < nums.length; j++) {
sum += nums[j]; // 将当前元素的值加到 sum 中
if (sum == target) {
maxLength = Math.max(maxLength, j - i + 1);
}
size++;
}
}
System.out.println("size:"+size);
return maxLength;
}
public static int findMaxSubarraySum(int[] nums, int target) {
int left = 0; // 左指针
int sum = 0; // 当前子数组的和
int maxLength = 0; // 最长子数组的长度
int size = 0;
for (int right = 0; right < nums.length; right++) {
sum += nums[right]; // 将当前元素的值加到sum中
boolean flag = false;
// 如果sum大于目标值,则移动左指针,将左边界的元素从sum中减去
while (sum > target) {
sum -= nums[left];
left++;
flag = true;
size ++;
}
if (!flag){
size ++;
}
// 如果sum等于目标值,更新最长子数组的长度
if (sum == target) {
maxLength = Math.max(maxLength, right - left + 1);
}
}
System.out.println("size:"+size);
return maxLength;
}
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5}; // 输入数组
int target = 9; // 目标值
int maxLength = findMaxSubarraySum(nums, target);
int maxLength2 = findMaxSubarrayLength(nums, target);
System.out.println("最长连续子数组的长度为:" + maxLength);
System.out.println("最长连续子数组的长度为2:" + maxLength2);
}
}
结果信息
可以看到至少比传统的少了一倍的循环次数