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

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

例如: arr=[3,-2,-4,0,6] , k=-2, 相加和小于或者等于-2的最长子数组为{3,-2,-4,0}, 所以结果返回4

解题思想:

预处理思想,把信息记录下来

累加和数组的改变

累加和数组中的最大值

用二分查找第一个大于等于某个值的位置

有序适合用二分查找

首先生成 sumArr  就是累加后的数组   这个数组大哦  因为 第一个为0 表示当没有任何一个数时的累加和为0

其次 生成sumArr的左侧最大数helpArr,  sumArr={0,1,3,2,7,5}  ->help={0,1,3,3,7,7}   我们只关心大于或等于某一个值的累加和最早出现的位置!

helpArr是sumArr每个位置上的左侧最大值数组,那么当然是有序的!

所以可以用二分查找法!查找大于或等于某一个值的累加和最早出现的位置。

package TT;

public class Test72 {

     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 +=arr[i];
             h[i+1]=Math.max(sum, h[i]);
         }

         sum = 0;
         int res = 0;
         int pre = 0;
         int len = 0;

         for(int i =0; i!=arr.length; i++){

             sum +=arr[i];
             pre = getLessIndex(h, sum-k);
             len = pre == -1 ? 0 : i-pre+1;
             res = Math.max(res, len);

         }
         return res;
     }

     public static int getLessIndex(int[] arr, int num){
         int low = 0;
         int high = arr.length-1;
         int mid = 0;
         int res=-1;
         while(low <= high){
             mid = (low+high)/2;
             if(arr[mid]>=num){
                 res=mid;
                 high=mid-1;
             }else {
                low = mid +1;
            }
         }

         return res;
     }

     public static void main(String[] args){

          int[] arr = new int[5];
          arr[0]=3;
          arr[1]=-2;
          arr[2]=-4;
          arr[3]=0;
          arr[4]=6;

        int x = maxLength(arr,-2);
        System.out.println(x);

     }

}

时间: 2024-08-29 08:44:18

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

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

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

一天一道算法题(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,该数组无序,但每个值均为正数,再给定一个正数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

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

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