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

(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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值