• 算法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);
        }
    }
  • 相关阅读:
    学习进度条(六)
    结对开发——-四则运算四
    结对开发——最大联通子数组的和
    团队项目成员和题目
    下载与安装APache Cordova
    学习进度条(五)
    构建之法阅读笔记05
    敏捷开发方法综述
    学习进度条(四)
    psp项目计划
  • 原文地址:https://www.cnblogs.com/sfnz/p/15788058.html
Copyright © 2020-2023  润新知