Maximum Average Subarray I

Given an array consisting of n integers, find the contiguous subarray of given length k that has the maximum average value. And you need to output the maximum average value.

给定一个由n个整数组成的数组,查找给定长度k的连续子数组,它具有最大的平均值。你需要输出最大的平均值。

Example 1:

Input: [1,12,-5,-6,50,3], k = 4
Output: 12.75
Explanation: Maximum average is (12-5-6+50)/4 = 51/4 = 12.75

Note:

  1. 1 <= k <= n <= 30,000.
  2. Elements of the given array will be in the range [-10,000, 10,000]


在解决这道题时,首先要搞清楚题意,其一,并不是求最大子段和。其二,k是已经给定的。
当明白了这两个点后,便可以进入解题阶段。
我解决这道题的做法便是,暴力查找。设定一个游标j,它从数组的初始位置(0号位置)开始,向后查k个单位,并计算j到j+k-1的值。然后依次相后移动j,重复上面操作。将每一次取得的和,作比较,保留最大的即可。附上代码:
public class Solution
{
    public double findMaxAverage(int[] nums, int k)
    {
       double a=helper(nums,k);
        return a;
    }
    public double helper(int []nums, int k)
    {
         //暂存字段和的值
        int max=0,t=0,j=0,sum=0;
        double average=0;
        //循环变量
        int  i=0;
        if(nums.length==1)
            max=nums[0];
        while((j+k-1)<=nums.length-1)
        {
            
            for(i=j;i<=j+k-1;i++)
            {
                t+=nums[i];
            }
            if(j==0)
                max=t;
                j++;
                max=Math.max(max,t);
                t=0;
        }
        average=(double)max/k;
        return average;
    }
}
需要注意的点:
①for循环中,i<=j+k-1这个条件,切不可因为i=j,便将条件改写为i<=i+k-1,因为i++后,下一次循环时i的值便发生了变化。
②要考虑到只有一个数值的数组,直接返回即可。
③需要注意到,每一次求值后比较时,都应该是和上一次的值进行比较,保留下较大值。故此,第一次求和时,一定要保留。以后的每次求和比较才可以顺利进行。
④要做到强类型转换。
⑤while循环条件一定要处理好,是nums.length-1,而不是nums.length,否则数组会超界。

大神做法:
public class Solution {
    public double findMaxAverage(int[] nums, int k) {
        long sum = 0;
        for (int i = 0; i < k; i++) sum += nums[i];
        long max = sum;
        for (int i = k; i < nums.length; i++) {
            sum += nums[i] - nums[i - k];
            max = Math.max(max, sum);
        }
        return max / 1.0 / k;
    }
}

这个做法十分巧妙,他忽略了每一个数组值得累加,而是通过减法间接实现增加。
sum += nums[i] - nums[i - k];
这一条语句是最关键的。加入k为2,那么第一次循环便是求nums[0],nums[1],这两个数组元素的和sum。那么递推相后,下一次便是求nums[1],nums[2]的和。经比较可以发现,nums[1]是多余的,因为每一次的求和,它都存在。那么。第二次求和时,可以在第一次的基础上,加上nums[2]与nums‘’[0]的差值。即为:nums[2]-nums[0]+sum==nums[2]-nums[0]+nums[1]+nums[0]=nums[1]+nums[2]。故以此类推,即可得到这一规律
sum += nums[i] - nums[i - k];

猜你喜欢

转载自blog.csdn.net/qq_36251958/article/details/76583992