一、题目背景
西瓜视频正在开发一个新功能,旨在将访问量达到80百分位数以上的视频展示在首页的推荐列表中。实现一个程序,计算给定数据中的80百分位数。
例如:假设有一个包含从1到100的整数数组,80百分位数的值为80,因为按升序排列后,第80%位置的数字就是80。
99 百分位数:假如有 N 个数据,将数据从小到大排列,99 百分位数是第 N99%位置处的数据(遇到小数时四舍五入获取整数)。一般计算逻辑是先排序,定位到 N99%的位置。返回该位置处的数据。同理,80 百分位数就是第 N*80%位置处的数据。
二、题目分析
-
百分位数的定义:
- N百分位数 是一个数据集中的第 N% 位置的值。如果数据集有 N 个数据项,将数据从小到大排列,第 N% 位置的数据就是 N百分位数。
- 例如,如果数据集的大小为 100,80百分位数的位置就是 100 * 0.80 = 80。如果有小数部分,通常会对其进行四舍五入,得到整数位置。
-
核心思路:
- 排序:首先将数据从小到大排序,因为百分位数是基于排序后的数据来计算的。
- 计算位置:计算数据集中的第 N * P 百分位数位置,P 为百分位的比例(在这里 P = 0.80,即 80%)。
- 取值:返回排序后数组中对应位置的数据。
三、算法步骤
-
输入处理: 输入数据是一个字符串,可能由多个数字组成,并且这些数字是通过逗号分隔的。首先,我们需要将这个字符串转换成一个整数列表。
data = list(map(int, data.split(','))) -
排序: 对数据进行升序排序。排序的目的是为了保证数据是按从小到大的顺序排列,以便于找到对应百分位数的位置。
data.sort() -
计算百分位数的位置: 根据数据的长度 N 和所需的百分位数(在本题中是 80%),计算该百分位数对应的位置。我们使用以下公式来计算位置:
percentile_index = round(N * 0.80) - 1N * 0.80计算出数据集中 80% 位置的浮动位置。需要注意的是,Python 的索引是从 0 开始的,因此需要减去 1 才能得到正确的索引。- 使用
round函数来确保位置是整数,特别是在某些情况下,计算出的百分位数位置可能是一个小数,round会将其四舍五入到最接近的整数。在一开始我使用的是int函数,但是在某些情况下,例如"2,15,3,16,1,3,13,12,4,6,2"该数组,使用int时会四舍五入得到答案为7,而使用round函数得到的才是正确答案9。
-
返回结果: 最后,返回排序后的数组中对应位置的元素,即为 80 百分位数的数据。
return data[percentile_index]
四、代码实现
def solution(data):
# Step 1: Convert the comma-separated string into a list of integers
data = list(map(int, data.split(',')))
# Step 2: Sort the data in ascending order
data.sort()
# Step 3: Calculate the position of the 80th percentile
N = len(data)
percentile_index = round(N * 0.80) - 1 # The index for 80th percentile (0-based)
# Step 4: Return the value at the 80th percentile position
return data[percentile_index]
五、复杂度分析
- 时间复杂度:排序操作的时间复杂度是
O(N * log N),其中 N 是数据的大小。其他操作如计算位置和返回结果的时间复杂度是O(1)。因此,总体时间复杂度为O(N * logN),主要由排序决定。 - 空间复杂度:我们使用了一个额外的列表来存储分割后的整数数据,因此空间复杂度为
O(N),其中 N 是数据的数量。
六、总结
这个程序的核心思想是:首先排序数据,然后根据数据集的大小计算所需的百分位数位置。通过简单的数学计算,我们可以在排序后的列表中找到对应的百分位数值。但是要注意:
- 排序是计算百分位数的基础,没有排序就无法正确计算百分位数。
- 百分位数的位置可能是小数,通常我们使用四舍五入来处理,以获得更合适的位置。
- 处理边界情况,如数据非常小的情况下,需要确保程序不会因越界或特殊情况导致错误。
本次刷题通过AI帮助我检查程序上的错误,不仅让整个过程变得更加清晰和高效,还帮助我意识到细节处理的关键,尤其是如何处理数据位置的四舍五入以及如何应对边界情况。