欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

给定值k的最长子数组长度

程序员文章站 2024-02-17 10:40:28
...

(1)给定一个数组,值全是正数,请返回累加和为给定值k的最长子数组长度。

(2)给定一个数组,值可以为正、负和0,请返回累加和为给定值k的最长子数组长度。

(1)l和r都只能往右滑动,不会回退

初始化: l = r = 0

如果窗口内[l, r]的和小于k, r++, sum += num[r]

如果和等于k,记录窗口大小并视情况更新返回结果值

如果和大于k,sum -= num[l], l右边滑

(2)必须以每个值为结尾的情况下累积和为k的最长子数组长度

利用一个map其中value为累积和,value为累积和最早出现的位置

eg:

  1. 3 2 1 3

i = 0: sum = 4:希望找到sum=-2的最早出现的位置,但是map.get(-2)为null, 因此ma.put(4, 0)

i = 1: sum = 7, 希望找到sum= 7 - 6(k)的最早出现的位置,但是map.get(1)为null, 因此ma.put(7, 1)

i = 2:sum =9, 希望找到sum= 9 - 6(k)的最早出现的位置,但是map.get(3)为null, 因此map.put(9, 2)

i = 3: sum = 10, 希望找到sum= 10 - 6(k)的最早出现的位置,但是map.get(4)为0, 因此[1,3]之间的和一定为k,map.put(10, 3)

.....

如果k = 4,按照以上的思路,map.get(0)为空,找不到结果,所有在刚开始就应该map.put(0, -1),防止错过0开始的所有的值,保证逻辑的完整性

public static int maxLength(int[] arr, int k){
	if(arr == null || arr.length == 0){
		return 0;
	}
	HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
	map.put(0, -1);
	int len = 0;
	int sum = 0;
	for(int i = 0; i < arr.length; i++){
		sum += arr[i];
		if(map.containsKey(sum - k)){
			len = Math.max(i - map.get(sum - k), len);
		}
		if(!map.containsKey(sum)){
			map.put(sum, i);
		}
	}
	return len;
}

(3)给定一个数组,值可以为正、负和0,请返回累加和小于等于k的最长子数组长度。

                    4 3 -2 6 7 -3 -1

arr               0 1 2 3 4 5 6

min_sum     4 1 -2 6 3 -4 -1

min_index    0 2 2 3 6 6 6

min_sum[i]: 以nums[i]为开头的连续子数组的和的最小值

min_index:最右边的索引下标

 

min_sum[i]

    如果min_sum[i+1] <= 0:

        =nums[i] + min_sum[i+1];

        min_index[i] = min_index[i+1]

    否则

        =nums[i]

       min_index[i] = i

接着继续利用滑动窗口来求解

l = r = 0