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

描述

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

输入描述:

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

输出描述:

输出一个整数表示答案

示例1

输入:
5 0
1 -2 1 1 1

输出:
3

思路

动态规划求解,用一个哈希表记录前缀和及其出现时的元素位置,当遇到一个没见过的前缀和presum时,就将其加入到哈希表中。如果哈希表中存在presum-k,说明从上一次presum出现的下一个位置到当前位置,数组元素的累加和为k,可以更新最长长度。这里可以看到presum出现的位置在更新最长长度时是需要用的,因此为了保证数组长度尽可能长,对于某个前缀和而言,哈希表中只存储它第一次出现的位置。

复制代码
import java.util.Scanner;
import java.util.HashMap;

public class Main{
    
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        
        int n = scanner.nextInt();
        int k = scanner.nextInt();
        int[] arr = new int[n];
        
        for(int i=0;i<arr.length;i++){
            arr[i]=scanner.nextInt();
        }
        //map中的key用来记录累加和,对应的value是这个累加和第一次出现的下标
        HashMap<Integer,Integer> map = new HashMap<>();
        //这个很关键的,当数组从0开始的累加和是k时就会用到,所以一定要保证<0,-1>已经在map中了,这个当前i个和等于k时就用到了
        map.put(0,-1);
        //sum用来记录数组前i项的和,length用来记录最后的答案
        int sum = 0;
        int length = 0;
        for(int i=0;i<arr.length;i++){
            sum += arr[i];
            //看看map中是否已经存过sum-k这个累加和了,有的话从那个值到目前的i就是length了
            if(map.containsKey(sum-k)){
                int j = map.get(sum-k);
                length = i-j>length?i-j:length;
            }
            if(!map.containsKey(sum)){
                map.put(sum,i);
            }
        }
      System.out.println(length);
    }
}
复制代码

 

posted @   思凡念真  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示