算法日志 --- 11.28---最大平均值和的分组

100 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

居家的第一天,浑身酸痛啊,前天还跳了一下操,今天酸到极致

最大平均值和的分组

该题出自力扣的813题 —— 最大平均值和的分组【中等题】

审题

给定数组 nums 和一个整数 k 。我们将给定的数组 nums 分成 最多 k 个相邻的非空子数组 。 分数 由每个子数组内的平均值的总和构成。 注意我们必须使用 nums 数组中的每一个数进行分组,并且分数不一定需要是整数。 返回我们所能得到的最大 分数 是多少。答案误差在 10-6 内被视为是正确的。

  • 这道题的题意很简单,但是容易掉以轻心,毕竟是中等题
  • 给出一个整型数组,和一个变量k
    • 整型数组切分成k个相邻的非空子数组
    • 需要注意的是,相邻,初次审题的时候,就看岔了,直接排序后获取
    • 最终返回一个最大的平均值和,也就是每个数组的平均值,最后总和
  • 可以注意的是,平均值意味着数量越多,则越小,那么大的数值单独作为一个分组
  • 换位思考,这是很经典的背包问题,也就是动态规划,分组对应着背包容量,数组元素对应着物品重量
  • 那么就可以利用二维数组去实现,实例化double的二维数组
    • 定义出double的数组作为前缀和
    • 遍历二维数组,遍历k个分组
      • 在K个分组内找出每个分组的最大值作为二维数组的值

编码

class Solution {
    public double largestSumOfAverages(int[] nums, int k) {
        double[][] dp = new double[nums.length + 1][k +1];
        double[] sum = new double[nums.length + 1];
        for (int i = 1; i <= nums.length; i++) {
            sum[i] = sum[i - 1] + nums[i - 1];
            dp[i][1] = sum[i] / i;
        }

        for (int i = 1; i <= nums.length; i++) {
            for (int j = 2; j <=k ; j++) {
                for (int l = 0; l < i; l++) {
                    dp[i][j] = Math.max(dp[i][j], dp[l][j-1] + (sum[i]-sum[l]) / (i-l));
                }

            }
            
        }
        return dp[nums.length][k];
    }
}

image.png