📅  最后修改于: 2023-12-03 15:23:02.870000             🧑  作者: Mango
给定一个数组A,包含N个正整数。定义以下函数:
f(x) = 数组A中所有小于等于x的数字的个数
写一个函数实现上述功能,并返回该数组的函数值。
def count_numbers_less_than_or_equal_to_x(n: int, arr: list[int], x: int) -> int:
pass
输入:
2
5
1 2 4 5 8
4
4
1 2 2 2 3
2
输出:
3
4
示例1: 数组A中小于等于4的数字有1、2、4,共3个。 示例2: 数组A中小于等于2的数字有1、2、2、2,共4个。
最简单的方法是使用两个嵌套循环,寻找小于等于x的数字个数。时间复杂度是$O(N^2)$。但是,这种方法的时间复杂度较高,不建议使用。
更优秀的解法是先排序数组,然后使用二分查找寻找第一个大于x的数字的下标,该下标即为小于等于x的数字的个数。时间复杂度为$O(N\log N)$。
要注意一点的是,在使用二分查找时,如果数组里存在与x相等的数字,则需要返回与x相等的最后一个数字的下标,这是因为题目要求小于等于x的数字个数,而不是小于x的数字个数。
def count_numbers_less_than_or_equal_to_x(n: int, arr: list[int], x: int) -> int:
# 先对数组排序
arr.sort()
# 在排好序的数组中查找第一个大于x的数字的位置
l, r = 0, n - 1
while l <= r:
mid = l + (r - l) // 2
if arr[mid] > x:
r = mid - 1
else:
l = mid + 1
# 如果数组中存在与x相等的数字,则需要从后往前查找最后一个相等的数字的位置
while r >= 0 and arr[r] == x:
r -= 1
return r + 1 # 返回小于等于x的数字的个数
该函数的时间复杂度为$O(N\log N)$,空间复杂度为$O(1)$。