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

题目:给定一个数组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......right]的和。开始时,sum=arr[0],即arr[0....0]的和。

3.变量len一直记录累加和为k的所有子数组中最大子数组的长度。开始时,len=0.

4.根据sum与k的比较结果决定是left移动还是right移动,具体如下:

(1)如果sum==k,说明arr[left.....right]累加和为k,如果arr[left.....right]长度大于len,则跟新len,此时因为数组所有的值都为正数,那么所有从left位置开始,在right之后的位置结束的子数组,累加和一定大于k。所以,令left加1,这表示我们开始考察以left之后的位置开始的子数组,同时令sum=sum-arr[left],sum此时表示arr[left+1.....right]

(2)如果sum小于k,说明arr[left.....right]还需要加上right后面的值,其和才可能达到k,所以,令right+1,sum+=arr[right].需要注意的是,right+1后是否越界。

(3)如果sum大于k,说明所有从left位置开始,在right之后的位置结束的子数组,累计和一定大于k,因此,我们考查以left之后的位置开始的子数组,同时令sum-=arr[left],sum此时表示arr[left+1....right]的累计和。

5.如果right<arr.length,重复步骤4.否则直接返回len,全部过程结束。

具体的参考代码如下:

 1 public  int  getMaxLength(int[] arr,int k)
 2 {
 3     if(arr==null || arr.length==0 || k<=0)
 4                   return 0;
 5     int left=0;
 6     int right=0;
 7     int sum=arr[0];
 8     int len=0;
 9     while(right<arr.length)
10    {
11        if(sum==k)
12      {
13         len=Math.max(len,right-left+1);
14         sum-=arr[left++];
15      }else if(sum<k)
16      {
17          right++;
18          if(right==arr.length)
19                break;
20         sum+=arr[right];
21     }
22    else
23        sum-=arr[left++];
24    }
25
26   return len;
27 }

时间: 2024-10-10 19:01:40

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

一天一道算法题(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=[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

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

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

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

题目描述 给定一个无序数组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 $ $-10

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

题目描述 给定无序数组,每个值均为正数,再给定整数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

【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

如何高效地判断数组中是否包含某特定值

 如何检查一个未排序的数组中是否包含某个特定值,这是一个在Java中非常实用并且频繁使用的操作.另外,这也是Stack Overflow上面非常受关注的问题.在得票数最多的答案中,可以看到,检查数组中是否包含特定值可以用多种不同的方式实现,但是时间复杂度差别很大.下面,我将为大家展示各种方法及其需要花费的时间. 1.检查数组中是否包含特定值的四种不同方法 1)使用List: 1 2 3 public static boolean useList(String[] arr, String ta