【发布时间】:2015-07-20 17:15:42
【问题描述】:
给定一个包含出生和结束年份的人员列表(都在1900 和2000 之间),找出活着的人数最多的年份。
这是我有点蛮力的解决方案:
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 中找到解决此问题的更有效方法。两者 - readability 和 efficiency 都很重要。此外,由于某种原因,我的代码不会打印 [1938, 1939] 而它应该打印。
更新
输入是元组的list,其中元组的第一个元素是人出生时的year,tuple 的第二个元素是死亡年份。
更新 2
结束年份(元组的第二部分)和人活着的年份一样重要(所以如果这个人在Sept 1939 死去(我们不关心月份),他实际上在 1939 年还活着,至少一部分)。这应该可以修复结果中缺少的 1939'。
最佳解决方案?
虽然可读性有利于@joran-beasley,但对于更大的输入,@njzk2 提供了最有效的算法。感谢@hannes-ovrén 在IPython notebook on Gist提供分析
【问题讨论】:
-
years[year] = 1对于初学者 -
@njzk2 从技术上讲,从可读性的角度来看,我认为您是正确的,但是每年[n] 都会被初始化为 0,并且仍然会正确生成“most_populated”年份。如果计数被退回,我同意你的看法,但只退回年份。
-
假设你有 10 个人在 2000 年出生,他们都在 2080 年死去。然后还有另外 10 个人在 2080 年出生,他们在 2160 年死去。你想要最大的活着的人吗? 10 或 20 或 15 还是别的什么?您对 2080 年的情况有何假设?
-
您的方法(对单个时间线进行建模)会奏效,但使用动态规划 的算法更为有效。 提示:Y 年初还活着的人 = Y 年前出生的总人数 - Y 年前死亡的总人数。请注意,(出生、死亡)的组合并不重要,只有日期。
-
对于一些相同想法的更难的问题,请参阅 Google Code Jam 的 The Great Wall code.google.com/codejam/contest/2437488/dashboard#s=p2