跟进任务

时间:2018-01-27 15:34:57

标签: python python-3.x performance

我今天解决了以下问题(不幸的是,我没有达到要求更好的时间复杂度)。

根据学生考试成绩列表,找到最佳平均成绩。每个学生在列表中可能有多个测试分数,最佳平均分数是该学生所有考试分数的平均分。 在下面的编辑器中完成bestAverageGrade函数。 它有一个参数,得分,这是一系列学生考试成绩。数组中的每个元素都是[学生姓名,测试分数]形式的双元素数组,例如[“鲍比”,“87”]。 对于能够在一段时间内处理更大输入的解决方案,即具有更快运行时复杂度的代码,将获得更多积分。

输入格式

输入参数分数是一个数组数组,其中每个子数组包含两个字符串:学生名称后跟测试分数作为字符串。您还必须包括条目数和每个条目的大小(这将始终为2)。请参阅下面的具体示例。测试分数可以是正整数或负整数。

输出格式

您的函数必须返回表示最佳平均成绩的单个整数。如果最终得到的平均等级不是整数,则应使用floor函数返回小于或等于平均值​​的最大整数。

返回0表示空输入。

示例输入0

[ [ "Bobby", "87" ],
  [ "Charles", "100" ],
  [ "Eric", "64" ],
  [ "Charles", "22" ] ]

输入为

4 2 鲍比87 查尔斯100 埃里克64 查尔斯22

示例输出0 87

这是我bestAverageGrade方法:

def bestAverageGrade(scores):
    list_of_students = set([x[0] for x in scores])
    averages = []
    for student in list_of_students:
        results = [float(x[1]) for x in scores if x[0] == student]
        averages.append(sum(results_of_student)/len(results))
    return math.floor(max(averages))

我怎样才能获得更好的时间复杂度?我知道现在列表列表被重复两次。

2 个答案:

答案 0 :(得分:0)

您可以多次遍历列表:每个学生一次。如果有多个学生,那么循环的数量可能会相当大,因此时间复杂度可能是 - 最坏情况 - O(n 2

我们可以使用一种方法,例如使用字典。我们可以定义一个字典grades,它将每个学生姓名映射到2元组(分子和分母)。在这种情况下,代码如下:

Vanilla Python

def bestAverageGrade(scores):
    grades = {}
    for student, grade in scores:
        grade = float(grade)
        current = grades.get(student)
        if current is None:
            grades[student] = grade, 1
        else:
            num, denom = current
            grades[student] = num + grade, denom + 1
    return math.floor(max(num/denom for num, denom in grades.values()))

熊猫

我们还可以通过使用Pandas来提升性能。例如:

import pandas as pd

def bestAverageGrade(scores):
    df = pd.DataFrame([[name, float(score)] for name, score in scores],
                      columns=['student', 'score'])
    return math.floor(df.groupby('student')['score'].mean().max())

因此,我们首先按学生分组并将均值作为'score'列的汇总。然后我们最大限度地利用所有这些学生。

答案 1 :(得分:0)

使用Javascript。

function bestAverageGrade(scores) {
          if(!Array.isArray(scores) || scores.length === 0) return 0;
          let duplicateFrequency = {};
          let sumFrequency = {};
          scores.forEach(item =>  {
            duplicateFrequency[item[0]] = duplicateFrequency[item[0]] ? duplicateFrequency[item[0]]+1 : 1;
         sumFrequency[item[0]] = sumFrequency[item[0]] ? sumFrequency[item[0]]+Number(item[1]) : Number(item[1]);
    })
      for( let props in duplicateFrequency) {
        sumFrequency[props] = Math.floor(sumFrequency[props] / duplicateFrequency[props])
      }

     return Math.max(...Object.values(sumFrequency))
    }

这里的时间复杂度为O(n)

方法:在这里,我们使用两个hashMap,一个用于存储重复项,另一个用于存储每个学生的总分。

然后,我们只考虑其中一个hashMap,然后将总和除以重复项。对结果取整以避免小数点。

最后,只需使用Math.max即可获取最大值。