class Solution { public double findMaxAverage(int[] nums, int k) { if (nums.length < k) return 0.0; double maxValue = Integer.MIN_VALUE, minValue = Integer.MAX_VALUE; for (int num : nums) { maxValue = Math.max(maxValue, num); minValue = Math.min(minValue, num); } double prevMid = maxValue, diff = maxValue; while (diff > 0.00001) { double mid = (minValue + maxValue) * 0.5; if (checkValue(nums, mid, k)) minValue = mid; else maxValue = mid; diff = Math.abs(prevMid - mid); prevMid = mid; } return minValue; } private boolean checkValue(int[] nums, double mid, int k) { double sum = 0, prev = 0, minSum = 0; for (int i = 0; i < k; i++) { sum += nums[i] - mid; } if (sum >= 0) return true; for (int i = k; i < nums.length; i++) { sum += nums[i] - mid; prev += nums[i - k] - mid;
// sum represents Sumj and prev represent Sumi. So Sumj - Sumi >= 0 should be fine.
// Since it does not require only k windows. j - i >= k should be fine. So we just find a i' with minmum value of continue sum that let Sumj - Sumi' >= 0
minSum = Math.min(prev, minSum); if (sum >= minSum) return true; } return false; } }