未排序数组中累加和小于或等于给定值的最长子数组长度

题目描述

给定一个无序数组arr,其中元素可正、可负、可0。给定一个整数k,求arr所有的子数组中累加和小于或等于k的最长子数组长度

要求

时间复杂度为O(n),空间复杂度为O(n)

示例

输入描述

第一行两个整数N, k。N表示数组长度,k的定义已在题目描述中给出
第二行N个整数表示数组内的数

输出描述

输出一个整数表示答案

示例1

输入

5 -2
3 -2 -4 0 6

输出

4

备注

\(1 \leq N \leq 10^5\)
$-10^9 \leq k \leq 10^9 $
$-100 \leq arr_i \leq100 $

思路比较巧妙,创建一个两个数组min_sum和ind,min_sum[i]表示到从输入数组末尾到i位置为止的最小子数组和,ind[i]记录这个数组的起始位置索引,注意这里是从后往前。
在求解的过程中,从前往后,对于每个位置计算满足条件最大子数组

n, k = map(int, input().strip().split(' '))
nums = list(map(int, input().strip().split(' ')))

min_sum = [0]*n
ind = [0]*n
min_sum[-1] = nums[-1]
ind[-1] = n-1
for i in range(n-1)[::-1]:
    min_sum[i] = min(min_sum[i+1], 0)+nums[i]
    if min_sum[i+1] <= 0:
        ind[i] = ind[i+1]
    else:
        ind[i] = i

#start表示子数组的开始,end表示结束位置后一位,s表示索引从start到end-1的子数组和
start = end = s = 0
res = 0
for start in range(n):
    end = max(end, start)
   # 对于每个start,end不必重新退回到新的start位置。这是因为start是向右移的,要寻找可能存在满足条件的更大的子数组的话,end只能在原有的end基础上右移,因此end不必要重新回到新的start位置。
    while end < n and s+min_sum[end] <= k:
        s += min_sum[end]
        end = ind[end]+1
    res = max(res, end-start)             #记录最长的子数组
    if end > start:                       #这里表示nums[start:end] > k,此时需要将start右移。当start移动到end-1时,此时s=0
        s -= nums[start]
print(res)

参考资料

https://www.nowcoder.com/questionTerminal/3473e545d6924077a4f7cbc850408ade?f=discussion

原文地址:https://www.cnblogs.com/zhaoyinghe/p/12106319.html

时间: 2024-11-07 19:27:27

未排序数组中累加和小于或等于给定值的最长子数组长度的相关文章

算法总结之 未排序数组中累加和小于或等于给定值的最长子数组长度

给定一个无序数组arr,其中元素可正.可负.可0,给定一个整数k,求arr所有的子数组中累加和小于或等于k的最长子数组长度. 例如: arr=[3,-2,-4,0,6] , k=-2, 相加和小于或者等于-2的最长子数组为{3,-2,-4,0}, 所以结果返回4 解题思想: 预处理思想,把信息记录下来 累加和数组的改变 累加和数组中的最大值 用二分查找第一个大于等于某个值的位置 有序适合用二分查找 首先生成 sumArr  就是累加后的数组   这个数组大哦  因为 第一个为0 表示当没有任何一

一天一道算法题(1)---未排序数组中累加和为给定值的最长子数组

题目 给定一个无序数组arr,其中元素可正,可负,可0,给定一个整数k.求arr所有的子数组中累加和为k的最长子数组长度. 分析 为了解答题目,引入一个概念,s(i)代表子数组arr[0..i]所有元素的累加和.那么子数组arr[j-1, i](0<=j<=i<arr.length)的累加和为s(i)-s(j-1). 1. 设置变量sum=0,表示从0位置开始一直加到i位置所有元素的和.设置变量len=0,表示累加和为k的最长子数组长度.定义一个HashMap,其中key是sum值,va

未排序数组中累加和为给定值的最长子数组长度

题目:给定一个数组arr,该数组无序,但每个值均为正数,再给定一个正数k.求arr得所有子数组中所有元素相加和为k的最长子数组长度. 解答:最优解可以做到时间复杂度为o(n),额外空间复杂度为o(1).首先用两个位置来标记子数组的左右两头,记为left和right,开始时都在数组的最左边(left=0,right=0).整体过程如下: 1.开始时变量left=0,right=0,代表子数组arr[left......right]. 2.变量sum始终表示子数组arr[left......righ

算法总结之 未排序正数数组中累加和为给定值的最长子数组长度

例如  arr=[1,2,1,1,1]   k=3 累加和为 3的最长子数组为[1,1,1]   所以结果为3 思路方法: 两个指针 left  和right   初始值都是0  都在左边 sum 代表 子数组 left.....right的和 len 一直记录累加和为k的所有子数组中最大子数组的长度 根据 sum与k的比较结果决定  left 跟 right 哪一个移动!!!! package TT; public class Test70 { public static int getMax

[程序员代码面试指南]数组和矩阵问题-未排序正数数组中累加和为给定值的最长子数组长度

题目描述 给定无序数组,每个值均为正数,再给定整数k.求arr中所有子数组中所有元素相加和为k的最长子数组长度.无则输出-1. 例: 输入 arr=[1,2,1,1,1],k=3 输出 3 解题思路 (时间复杂度O(N),空间复杂度O(1)) 维护指针l,r表示子数组区间.初始l=r=0,向右移动至r=arr.length结束. 维护当前子数组和sum,及到当前为止满足题意的最大len.初始sum=arr[0],len=-1. 每次比较sum和k,根据情况选择移动l还是r,并更新sum和len.

未排序数组中累加和为指定值得最长子数组序列问题

1.题目: 给定一个无序数组,其中元素 可正可负可0,给定一个k,求arr中所有的子数组累加和为k的最长子数组长度. 1 // maxLength.cpp : 定义控制台应用程序的入口点. 2 //未排序数组中累加和为指定值的最长子数组长度 3 //数组元素可正.可负.可0 4 5 #include "stdafx.h" 6 #include<iostream> 7 #include <map> 8 #include <iterator> 9 10

累加和小于或等于定值得最长子数组的长度

package com.hzins.suanfa; /** * 累加和小于或等于定值得最长子数组的长度 * @author Administrator * */ public class Demo1 { public static int maxLength(int[] arr, int k){ int[] h = new int[arr.length + 1]; int sum = 0; h[0] = sum; for(int i = 0;i !=arr.length;i ++){ sum +

【c语言】二维数组中的查找,杨氏矩阵在一个二维数组中,每行都依照从左到右的递增的顺序排序,输入这种一个数组和一个数,推断数组中是否包括这个数

// 二维数组中的查找,杨氏矩阵在一个二维数组中.每行都依照从左到右的递增的顺序排序. // 每列都依照从上到下递增的顺序排序.请完毕一个函数,输入这种一个数组和一个数.推断数组中是否包括这个数 #include <stdio.h> #define col 4 #define rol 4 int yang(int(*p)[col], int num) { int i = 0; int j = col - 1; while (j+1) { int *q = &(p[i][j]); if

数组中累加和为k的最大子数组的长度

package com.hzins.suanfa; import java.util.HashMap; public class demo { /** * 数组中累加和为k的最大子数组的长度 * @param arr * @param k * @return */ public static int maxLengh(int[] arr,int k){ if(arr == null || arr.length == 0){ return 0; } HashMap<Integer, Integer