当前位置:   article > 正文

315 计算右侧小于当前元素的个数(树状数组)_长方形内点的数量 树状数组

长方形内点的数量 树状数组

1. 问题描述:

给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是  nums[i] 右侧小于 nums[i] 的元素的数量。

示例:

输入:nums = [5,2,6,1]
输出:[2,1,1,0] 

解释:

5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素提示:
0 <= nums.length <= 10 ^ 5
-10 ^ 4 <= nums[i] <= 10 ^ 4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/

2. 思路分析:

这道题目其实有很多种的解决方法,这里使用树状数组的解法。其实想到树状数组的时候那么剩下来的就不难了(关键是需要想到这个),树状数组主要有两个功能:① 将数组中的某个位置加上一个值 ② 求解[1: x]区间的前缀和;对应的这道题目我们其实可以每遍历一个数字x,在树状数组tr中查找一下[1: x - 1]的个数即可,查找x之后那么将树状数组对应的当前位置加上一个1即可,例如题目中的[5,2,6,1],我们可以逆序遍历列表,从1开始发现结果为0所以右侧小于1的个数为0,然后第二个数字6寻找一下tr[1:5]区间的个数,发现结果为1所以右侧小于6的个数为1,第三个数字为2找一下tr[1:2]的个数为1,发现结果为1所以右侧小于2的个数为1,同理5的右侧小于5的个数结果为2。在树状数组对应的nums[i]位置加上1即可,查找元素的时候在[1: x - 1]区间内查找元素个数即可。

3. 代码如下:

  1. from typing import List
  2. class Solution:
  3. tr = None
  4. # 返回最低位二进制的1对应的数字
  5. def lowbit(self, x: int):
  6. return x & -x
  7. # 查找[1:x]的前缀和
  8. def query(self, x: int):
  9. tr = self.tr
  10. i = x
  11. res = 0
  12. while i > 0:
  13. res += tr[i]
  14. i -= self.lowbit(i)
  15. return res
  16. # 在树状数组的x位置加上v
  17. def add(self, x: int, v: int):
  18. i = x
  19. tr = self.tr
  20. while i < len(tr):
  21. tr[i] += v
  22. i += self.lowbit(i)
  23. def countSmaller(self, nums: List[int]) -> List[int]:
  24. n = len(nums)
  25. # 这里以
  26. self.tr = [0] * 20002
  27. res = [0] * n
  28. for i in range(n - 1, -1, -1):
  29. # 因为nums有可能是负数最小为10000所以需要加上10001这样对应的树状数组最小的也从下标1开始, 其实是映射的关系(偏移量)
  30. res[i] = self.query(nums[i] + 10001 - 1)
  31. self.add(nums[i] + 10001, 1)
  32. return res
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/87173
推荐阅读
相关标签
  

闽ICP备14008679号