813. 最大平均值和的分组(Python)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了813. 最大平均值和的分组(Python)相关的知识,希望对你有一定的参考价值。

参考技术A 难度:★★★☆☆
类型:数组
方法:动态规划

力扣链接请移步 本题传送门
更多力扣中等题的解决方案请移步 力扣中等题目录

我们将给定的数组 A 分成 K 个相邻的非空子数组 ,我们的分数由每个子数组内的平均值的总和构成。计算我们所能得到的最大分数是多少。

注意我们必须使用 A 数组中的每一个数进行分组,并且分数不一定需要是整数。

示例:
输入:
A = [9,1,2,3,9]
K = 3
输出: 20
解释:
A 的最优分组是[9], [1, 2, 3], [9]. 得到的分数是 9 + (1 + 2 + 3) / 3 + 9 = 20.
我们也可以把 A 分成[9, 1], [2], [3, 9].
这样的分组得到的分数为 5 + 2 + 6 = 13, 但不是最大值.
说明:

1 <= A.length <= 100.
1 <= A[i] <= 10000.
1 <= K <= A.length.
答案误差在 10^-6 内被视为是正确的。

数组问题常用动态规划来解决。动态规划的精髓在于,把一个难以解决的大问题转化为若干个可以通过有限次重复解决的简单问题。接下来从动态规划的几个要素进行介绍:

【数组定义】
我们定义一个二维数组dp,维度为输入数组A的维度×K,dp[i][k]表示数组A[:i+1]被分成k+1组时,可以得到的最大分数(各组平均值的和)。这里尤其需要注意python下标和它代表的变量的物理含义之间正好相差1的。

【初始状态】
我们可以很快得知的信息是,如果数组只被分为一组的情况。因此可以先把k=0的一列填好。这一列各个位置dp[i][0]的填充规则,就是A[:i]的均值。

【递推公式】
我们以分组数k和下标i递增的方式,构造嵌套循环。这里还需要留意一个情况,就是填充dp[i][k]时,需要考虑到获得当前位置的各种情况的分组,因此借助一个中间下标变量j,范围从0到i,也就是说,我们把数组A[:i+1]从下标j砍成了两半,因此当前位置处的值可以填充为:

dp[i][k] = max(dp[i][k], dp[j][k-1]+average(j+1, i+1))

这里average是一个函数,用来计算A[i:j]子数组的均值。这里把i和j+1的原因是我们定义dp数组的物理意义决定的。

有了这个递推公式,就可以迭代进行计算了,
注意k的范围是从1到K,因为k=0的一列已经算好了;
i的范围是从k到len(A),因为组的个数不能比数组中数字的个数还要多;
j的范围是小于i,因为必须要保证可以把A[:i+1]分开。

【最后结果】

最终范围dp[-1][-1]也就是最后计算出的值,就可以代表题目所要求的结果。

如有疑问或建议,欢迎评论区留言~

有关更多力扣中等题的python解决方案,请移步 力扣中等题解析

Java8 Stream针对List先分组再求和最大值最小值平均值等

解题思路:JAVA8使用stream()根据类型对List进行分组统计。

核心功能代码片段

 //分组求和
        Map<String, LongSummaryStatistics> collect = list.stream().collect(
                Collectors.groupingBy(Fruit::getType,
                        Collectors.summarizingLong(Fruit::getTotal)));
        for (Map.Entry<String, LongSummaryStatistics> entry : collect.entrySet()) 
            LongSummaryStatistics longSummaryStatistics = entry.getValue();
            System.out.println("----------------key----------------" + entry.getKey());
            System.out.println("求和:" + longSummaryStatistics.getSum());
            System.out.println("求平均" + longSummaryStatistics.getAverage());
            System.out.println("求最大:" + longSummaryStatistics.getMax());
            System.out.println("求最小:" + longSummaryStatistics.getMin());
            System.out.println("求总数:" + longSummaryStatistics.getCount());
        

演示功能代码

package com.zzg.test;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.json.JSONUtil;

/**
 * 基于Java8 分组再统计
 * @author zzg
 *
 */
public class GroupByStatissticsTest 
	
	static List<Fruit> initDate()
		List<Fruit> list = new ArrayList<Fruit>();
		
		Fruit one = new Fruit();
		one.setName("苹果一级");
		one.setSid("1");
		one.setPrice(new BigDecimal("123456.98").setScale(BigDecimal.ROUND_HALF_UP, 2) );
		one.setTotal(1100L);
		one.setType("1");
		
		
		Fruit two = new Fruit();
		two.setName("苹果二级");
		two.setSid("2");
		two.setPrice(new BigDecimal("123546.98").setScale(BigDecimal.ROUND_HALF_UP, 2) );
		two.setTotal(89L);
		two.setType("1");
		
		Fruit three = new Fruit();
		three.setName("苹果三级");
		three.setSid("3");
		three.setPrice(new BigDecimal("987.98").setScale(BigDecimal.ROUND_HALF_UP, 2) );
		three.setTotal(1039L);
		three.setType("1");
		
		Fruit four = new Fruit();
		four.setName("梨子一级");
		four.setSid("4");
		four.setPrice(new BigDecimal("97.98").setScale(BigDecimal.ROUND_HALF_UP, 2) );
		four.setTotal(39L);
		four.setType("2");
		
		Fruit five = new Fruit();
		five.setName("梨子二级");
		five.setSid("5");
		five.setPrice(new BigDecimal("970.98").setScale(BigDecimal.ROUND_HALF_UP, 2) );
		five.setTotal(399L);
		five.setType("2");
		
		Fruit six = new Fruit();
		six.setName("西瓜一级");
		six.setSid("6");
		six.setPrice(new BigDecimal("1970.98").setScale(BigDecimal.ROUND_HALF_UP, 2) );
		six.setTotal(2399L);
		six.setType("3");
		
		list.add(one);
		list.add(two);
		list.add(three);
		list.add(four);
		list.add(five);
		list.add(six);
		return list;
	

	public static void main(String[] args) 
		// TODO Auto-generated method stub
		List<Fruit> list = initDate();
		
		  //分组
        Map<String,List<Fruit>> map = list.stream().collect(Collectors.groupingBy(Fruit::getType));
        for (Map.Entry<String, List<Fruit>> entry : map.entrySet()) 
            System.out.println("分组" + JSONUtil.toJsonStr(entry));
        
        
      //分组求和
        Map<String, LongSummaryStatistics> collect = list.stream().collect(
                Collectors.groupingBy(Fruit::getType,
                        Collectors.summarizingLong(Fruit::getTotal)));
        for (Map.Entry<String, LongSummaryStatistics> entry : collect.entrySet()) 
            LongSummaryStatistics longSummaryStatistics = entry.getValue();
            System.out.println("----------------key----------------" + entry.getKey());
            System.out.println("求和:" + longSummaryStatistics.getSum());
            System.out.println("求平均" + longSummaryStatistics.getAverage());
            System.out.println("求最大:" + longSummaryStatistics.getMax());
            System.out.println("求最小:" + longSummaryStatistics.getMin());
            System.out.println("求总数:" + longSummaryStatistics.getCount());
        


	
	
	static class Fruit
		private String sid;
		private String name;
		private String type;
		private Long total;
		private BigDecimal price;
		public String getSid() 
			return sid;
		
		public void setSid(String sid) 
			this.sid = sid;
		
		public String getName() 
			return name;
		
		public void setName(String name) 
			this.name = name;
		
		public String getType() 
			return type;
		
		public void setType(String type) 
			this.type = type;
		
		public Long getTotal() 
			return total;
		
		public void setTotal(Long total) 
			this.total = total;
		
		public BigDecimal getPrice() 
			return price;
		
		public void setPrice(BigDecimal price) 
			this.price = price;
		
		
		
		
	


效果截图

 

以上是关于813. 最大平均值和的分组(Python)的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 0813. 最大平均值和的分组

LeetCode 0813. 最大平均值和的分组

leetcode 813. Largest Sum of Averages

Python:如何获取按 id 分组的每列的 n 个最大值的平均值

所有可能和的最小值、最大值、平均值和中值 (Ruby)

R - 对连续变量标题进行分组,将分类变量因子作为行并聚合为最小值、最大值、平均值