【LeetCode】数组-1(643)-返回规定长度k的最大子数组的平均数
好久没有刷LeetCode了,准备重拾并坚持下去,每天刷个两小时。今天算是开始的第一天,不过出师不利,在一道很简单的题目上墨迹半天。不过还好,现在踩过的坑,应该都不会白踩,这些可能都是以后程序员路上稳固的基石哦。任何优秀的程序员不都是这样过来的嘛,坚持就好。
注意:大家练习时同样要注意代码的风格,这一点推荐上lintcode测试一下,练习几次风格自然就好了。
下面开始写第一题的解题过程(包括写错的过程)
思路一:累加数组
1. 求出数组的累加数组(循环遍历,每一项等于前一项的和)
2. k个数的和等于 i 位置上的数减去 i - k 位置上的数(对于坐标比较迷糊的同学,推荐你们在稿纸上画画就明白了)。
第一遍错误的代码(黄色标记处错误):
1 public class Solution { 2 public double findMaxAverage(int[] nums, int k) { 3 if (nums == null || nums.length < 1) { 4 return -1; 5 } 6 int[] ans = new int[nums.length]; 7 double maxSum = 0; 8 ans[0] = nums[0]; 9 for (int i = 1; i < nums.length; i++) { 10 ans[i] = nums[i] + nums[i - 1]; 11 } 12 maxSum = ans[k - 1]; 13 for (int i = k; i < nums.length; i++) { 14 double curSum = (double)ans[i] - ans[i - k]; 15 if (curSum > maxSum) { 16 maxSum = curSum; 17 }else { 18 continue; 19 } 20 } 21 return maxSum / k; 22 } 23 }
nums改成ans就正确了。
时间复杂度:O(n)只是两遍遍历,没有嵌套。
空间复杂度:O(n)申请了一个数组
思路二:滑动窗口
维护一个“和”数组,只有k个元素,从k+1开始,每次右边加一个元素,左边减一个元素。
相比一的好处:不用申请数组了,而且效率也高了,减少了重复计算。
这次终于BugFree了,不容易啊。
1 public class Solution { 2 public double findMaxAverage(int[] nums, int k) { 3 if (nums.length < 1 || nums == null) { 4 return -1; 5 } 6 int sum = 0; 7 int max = 0; 8 for (int i = 0; i < k; i++) { 9 sum += nums[i];// 先求前k个数的和,之后不断维护这个数组即可。 10 max = sum; 11 } 12 for (int i = k; i < nums.length; i++) { 13 sum += nums[i] - nums[i - k]; 14 if (sum > max) { 15 max = sum; 16 } 17 } 18 return max * 1.0 / k; 19 } 20 }
时间复杂度:O(n)只是遍历一遍
空间复杂度:O(1)