813. 最大平均值和的分组
思路:长度为
N
的数组,第一个分割位置在i位置时的平均值假设为
avg
, 剩余
N - i
长度的数组分割为
k - 1
个相邻子数组的最大分数平均值为
cur
。遍历数组中每一个
i
所在的位置,同时更新最大值
avg + cur
递归
class Solution {
public double largestSumOfAverages(int[] nums, int k) {
int N = nums.length;
return process(nums, N,0, k);
}
private double process(int[] nums, int N, int index, int k) {
if (k == 0) {
return 0.0;
}
if (index >= N) {
return 0.0;
}
// k = 1时直接返回剩余数组的均值
if (k == 1) {
int sum = 0;
for (int i = index; i < N; i++) {
sum += nums[i];
}
return (sum * 1.0) / (N - index);
}
int sum = 0;
double res = 0.0;
// 枚举每个 i 所在的位置
for (int i = index; i < N; i++) {
sum += nums[i];
double avg = (sum * 1.0) / (i - index + 1);
// 剩余数组的最大均值
double cur = process(nums, N, i + 1, k - 1);
res = Math.max(res, avg + cur);
}
return res;
}
}
递归会超时,因为存在许多重复计算,所以可以加缓存,也就是记忆化搜索
记忆化搜索
class Solution {
public double largestSumOfAverages2(int[] nums, int k) {
int N = nums.length;
double[][] dp = new double[N + 1][k + 1];
for (int i = 0; i < N + 1; i++) {
Arrays.fill(dp[i], -1.0);
}
return process2(nums, N,0, k, dp);
}
private double process2(int[] nums, int N, int index, int k, double[][] dp) {
if (dp[index][k] != -1.0) {
return dp[index][k];
}
if (k == 0) {
dp[index][k] = 0.0;
return dp[index][k];
}
if (index >= N) {
dp[index][k] = 0.0;
return dp[index][k];
}
if (k == 1) {
int sum = 0;
for (int i = index; i < N; i++) {
sum += nums[i];
}
dp[index][k] = (sum * 1.0) / (N - index);
return dp[index][k];
}
int sum = 0;
double res = 0.0;
for (int i = index; i < N; i++) {
sum += nums[i];
double avg = (sum * 1.0) / (i - index + 1);
double cur = process2(nums, N, i + 1, k - 1, dp);
res = Math.max(res, avg + cur);
}
dp[index][k] = res;
return dp[index][k];
}
}
动态规划
将递归改写成动态规划
class Solution {
public double dpWays(int[] nums, int k) {
int N = nums.length;
double[][] dp = new double[N + 1][k + 1];
for (int i = N - 1; i >= 0; i--) {
for (int j = 1; j < k + 1; j++) {
if (j == 1) {
int sum = 0;
for (int l = i; l < N; l++) {
sum += nums[l];
}
dp[i][j] = (sum * 1.0) / (N - i);
} else {
int sum = 0;
double res = 0.0;
for (int l = i; l < N; l++) {
sum += nums[l];
double avg = (sum * 1.0) / (l - i + 1);
double cur = dp[l + 1][j - 1];
res = Math.max(res, avg + cur);
}
dp[i][j] = res;
}
}
}
return dp[0][k];
}
}
版权声明:本文为qq_43142792原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。