python - 用 Python 找出在世人数最多的年份

标签 python algorithm

给定一个包含出生年份和结束年份(都在 19002000 之间)的人的列表,找出在世人数最多的年份。

这是我的蛮力解决方案:

def most_populated(population, single=True):
    years = dict()
    for person in population:
        for year in xrange(person[0], person[1]):
            if year in years:
                years[year] += 1
            else:
                years[year] = 0
    return max(years, key=years.get) if single else \
           [key for key, val in years.iteritems() if val == max(years.values())]

print most_populated([(1920, 1939), (1911, 1944),
                      (1920, 1955), (1938, 1939)])
print most_populated([(1920, 1939), (1911, 1944),
                      (1920, 1955), (1938, 1939), (1937, 1940)], False)

我正试图在 Python 中找到一种更有效的方法来解决这个问题。 可读性效率 都很重要。此外,出于某种原因,我的代码不会打印 [1938, 1939] 而它应该。

更新

输入是元组的列表,其中元组的第一个元素是人出生的元组的第二个元素 是死亡年份。

更新 2

结束年份(元组的第 2 部分)和此人在世的年份一样重要(所以如果此人在 1939 年 9 月 去世(我们不关心月份),他实际上在 1939 年还活着,至少是其中的一部分)。这应该可以修复结果中缺失的 1939'。

最佳解决方案?

虽然可读性有利于 @joran-beasley ,对于更大的输入,最有效的算法由 @njzk2 提供.感谢@hannes-ovrén 在 IPython notebook on Gist 中提供分析

最佳答案

我想到的另一个解决方案:

  • 创建 2 个表,birthdatesdeathdates
  • 在这些表中累积出生日期和死亡日期。
  • 浏览这些表格以累积当时活着的人数。

总复杂度为 O(n)

实现

from collections import Counter

def most_populated(population, single=True):
    birth = map(lambda x: x[0], population)
    death = map(lambda x: x[1] + 1, population)
    b = Counter(birth)
    d = Counter(death)
    alive = 0
    years = {}
    for year in range(min(birth), max(death) + 1):
        alive = alive + b[year] - d[year]
        years[year] = alive
    return max(years, key=years.get) if single else \
           [key for key, val in years.iteritems() if val == max(years.values())]

更好

from collections import Counter
from itertools import accumulate
import operator

def most_populated(population, single=True):
    delta = Counter(x[0] for x in population)
    delta.subtract(Counter(x[1]+1 for x in population))
    start, end = min(delta.keys()), max(delta.keys())
    years = list(accumulate(delta[year] for year in range(start, end)))
    return max(enumerate(years), key=operator.itemgetter(1))[0] + start if single else \
           [i + start for i, val in enumerate(years) if val == max(years)]

关于python - 用 Python 找出在世人数最多的年份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31522450/

相关文章:

python - 用于自动生成 Python 导入语句的 Vim 插件(不使用 Rope)

python - 如何在 Django 中创建仅包含用户名的用户模型?

java - 这里正确的架构设计是什么?

algorithm - 针对以下问题提出 O(logm) 算法

javascript - 旋转六边形上的索引

python - 在python中读取文件

VSCode 中的 Python 路径 : The system cannot find the path specified

python - 如何从文本文件中的 jpeg 图像文件列表中打开图像 - 变量形成

php - 如何将列数据转换为行数据

c++ - 在字符串中查找所有具有最大长度的有序序列