zoukankan      html  css  js  c++  java
  • 325.长度最大的子数组

    题目

    给定一个整数数组(无序且有正有负)和一个目标值,求这个数组中子数组的和为目标值的子数组的最大长度。

    思路

    子数组是连续的,s[i]表示从0i位置的累加和,s[j]表示0j位置的累加和,那么从j+1~i位置的累加和为s[j]-s[i],他可以表示任意子数组的累加和,如果这个累加和就是目标值aim,那么找出长度最长的即可。
    遍历一遍数组,并求出各个位置的累加和,如在i位置时求得为s[i],在此我们是否可以得到在0-i之间的所有子数组中是否存在累加和为aim的,只需要查询下s[i]-aim 这个值是否在之前计算累加和的过程中出现过。

    代码

         /*
         * 给定一个全是正数的数组arr, 和一个整数aim, 求累加和为aim的最大子数组长度
         * 基础:子数组是数组中连续的n个元素
         */
        public static int getMaxLength(int[] arr ,int aim){
            if(arr==null||arr.length==0)
                return 0;
            int sum=0;
            int len=0;
            //sum记录从0到i位置处的连续累加和,哈希表记录以value下标结尾从0开始的累加和key
            HashMap<Integer,Integer> map=new HashMap<Integer, Integer>();
            //sum [0----i]  aim  [j+1-----i] sum-aim [0---j]  要求的数从j+1开始,当j+1=0时,即从开头开始,j=-1;
            //不加任何一个数时,累加和为0,此时下标为-1,就表示还没有添加任何数
            map.put(0, -1);
            for(int i=0;i<arr.length;i++){
                sum+=arr[i];
                if(map.containsKey(sum-aim)){//判断哈希表中现在是否存在sum-aim,如果存在得到他的下标j,那么从j+1到i就是子数组和为aim
                    //记录的下标应该为最早出现的j 后面再出现不更新(因为要求最大长度)
                    len=Math.max(i-map.get(sum-aim), len);
                }
                //在后续遍历过程中如果出现了相同的sum,不更新
                if(!map.containsKey(sum))//该处的sum值是第一次出现,后面再出现的话不更新(因为要求最大长度)
                    map.put(sum, i);
            }
            return len;
        }
    

    如果给定的数组全是正整数,那么这道题也可以用滑动窗口的方法解决。滑动窗口法要求在右界固定的情况下,求最大的左界,即通常用来求满足条件的最短子数组。但是由于数组全是正整数,在右界固定的条件下,如果存在满足条件的左界,那这个左界是唯一的。因此使用滑动窗口法可找到所有和等于aim的子数组,从中找出最长的那个就行。
    最开始sum=0,right=0,sum一直加arr[right],直到sum>=aim。当sum大于等于aim时,减去arr[left]。

       int maxSubArrayLen(int aim, int[] arr) {
            if(arr==null||arr.length==0||aim<0)
                return 0;
            int sum=arr[0];
            int len=0;
            int left=0;
            int right=0; //sum 为left -right 之间的数之和
            while(right<arr.length){
                if(sum==aim){
                    len=Math.max(len, right-left+1);
                    sum-=arr[left++];
                }
                else if(sum<aim){
                    right++;
                    if(right==arr.length)
                        break;
                    sum+=arr[right];
                }
                else {
                    sum -= arr[left++];
                }
            }
            return len;
        }
    

    参考:https://blog.csdn.net/yjpeng125/article/details/78992123

  • 相关阅读:
    spark on yarn模式下内存资源管理(笔记1)
    面试题10.3-变态跳台阶
    面试题10.2-青蛙跳
    面试题9-斐波那契数列
    面试题9-用两个栈来实现一个队列,完成队列的Push和Pop操作
    面试题6:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList
    鸢尾花数据集-iris.data
    class之cls
    python 装饰器
    supervisor python开发的进程管理工具
  • 原文地址:https://www.cnblogs.com/Frank-Hong/p/14176508.html
Copyright © 2011-2022 走看看