python创建变量revenue、并赋值为98765_Python 树状数组(二)—— 离散化

提到树状数组的具体应用就不得不提起离散化

什么是离散化呢?

很多时候,我们并不关心数组中每个值的大小,只关心它们的序的关系。1. 在求数组的逆序数的时候,98765 和 54321 具有相同的逆序数

2. 求数组的每个数右边有多少个更小的数

通常我们把 一个具有 n 个 unique values 的数组映射到 range [0, n)的整数的操作叫做离散化。

在使用树状数组解决上述问题的时候就必须要用到离散化!!!

以第二个问题为例,如果我们有一个离散化好的数组[3, 1, 0, 2],从右往左读。

第一步,初始化一个全0的、数组长度为4的树状数组类 (zero-indexed)

第二步,在树状数组的位置 2 加上1 (因为2是[1,0,2]的最后一个)

第三步,在树状数组的位置 0 加上1 (此处其实省略了 query)

第四步,在树状数组的位置 1 加上1,并计算(query)树状数组位置 1 之前的和(这个和是1),这个和就是数字1的右边比1小的数的个数!

第五步,在树状数组的位置 3 加上1,并计算(query)树状数组位置 3 之前的和(这个和是3),这个和就是数字3的右边比3小的数的个数!

相信你已经对离散化的作用有一定的了解了。那么,我们如何高效的实现对一个数组/序列的离散化呢??离散化需要的时间又是多少呢??

关于离散化,其实还有一个需要考虑的,就是数组有无重复元素,重复元素在离散化后的数组也需要具有相同的值。如果没有重复元素,程序会变得简单一些。以下都按数组有重复元素来考虑。

离散化方法一:排序后使用哈希映射

def discretization(l: list) -> list:

res = []

s = sorted(set(l))

d = {x:i for i, x in enumerate(s)}

for a in l:

res.append(d[a])

return res

这种方式的时间复杂度出在排序上,空间上需要维护一个哈希表

离散化方法二:排序后使用二分查找

import bisect

def discretization(l: list) -> list:

res = []

s = sorted(set(l))

for a in l:

res.append(bisect.bisect_left(s, a) + 1)

return res

这种方法的好处在于不需要一个哈希表了,但是二分查找需要更多的时间;空间更省但是时间更多。

关于二分查找,python有bisect标准库,C++的algorithm提供了lower_bound和upper_bound函数,Java有Arrays.binarySearch函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值