|
| 1 | +# |
| 2 | +# @lc app=leetcode.cn id=315 lang=python |
| 3 | +# |
| 4 | +# [315] 计算右侧小于当前元素的个数 |
| 5 | +# |
| 6 | +# https://leetcode-cn.com/problems/count-of-smaller-numbers-after-self/description/ |
| 7 | +# |
| 8 | +# algorithms |
| 9 | +# Hard (37.52%) |
| 10 | +# Likes: 63 |
| 11 | +# Dislikes: 0 |
| 12 | +# Total Accepted: 2.9K |
| 13 | +# Total Submissions: 7.8K |
| 14 | +# Testcase Example: '[5,2,6,1]' |
| 15 | +# |
| 16 | +# 给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 |
| 17 | +# nums[i] 的元素的数量。 |
| 18 | +# |
| 19 | +# 示例: |
| 20 | +# |
| 21 | +# 输入: [5,2,6,1] |
| 22 | +# 输出: [2,1,1,0] |
| 23 | +# 解释: |
| 24 | +# 5 的右侧有 2 个更小的元素 (2 和 1). |
| 25 | +# 2 的右侧仅有 1 个更小的元素 (1). |
| 26 | +# 6 的右侧有 1 个更小的元素 (1). |
| 27 | +# 1 的右侧有 0 个更小的元素. |
| 28 | +# |
| 29 | +# |
| 30 | +# 思路: 构建一个二叉搜索树,左子树小于等于根节点,右子树大于根节点 |
| 31 | +# 节点内记录下标,所有左节点的个数,以及右侧小于该节点的总数 |
| 32 | +# 若插入节点小于等于当前节点,则当前节点的左节点总数+1 |
| 33 | +# 若插入节点大于当前节点,则当前节点的右侧小于该节点的总数=当前节点的左节点总数+1(当前节点) |
| 34 | +# 最后深度遍历 |
| 35 | + |
| 36 | + |
| 37 | +class BST(object): |
| 38 | + def __init__(self, index, val): |
| 39 | + self.left = None |
| 40 | + self.right = None |
| 41 | + self.index = index |
| 42 | + self.val = val |
| 43 | + # 右侧小于该节点的总数 |
| 44 | + self.count = 0 |
| 45 | + # 左子树总数 |
| 46 | + self.left_count = 0 |
| 47 | + |
| 48 | + def insert(self, node): |
| 49 | + if node.val <= self.val: |
| 50 | + self.left_count += 1 |
| 51 | + if not self.left: |
| 52 | + self.left = node |
| 53 | + else: |
| 54 | + self.left.insert(node) |
| 55 | + else: |
| 56 | + node.count += self.left_count + 1 |
| 57 | + if not self.right: |
| 58 | + self.right = node |
| 59 | + else: |
| 60 | + self.right.insert(node) |
| 61 | + |
| 62 | + |
| 63 | +class Solution(object): |
| 64 | + def countSmaller(self, nums): |
| 65 | + """ |
| 66 | + :type nums: List[int] |
| 67 | + :rtype: List[int] |
| 68 | + """ |
| 69 | + if not nums: |
| 70 | + return [] |
| 71 | + nums = nums[::-1] |
| 72 | + root = BST(0, nums[0]) |
| 73 | + for i in range(1, len(nums)): |
| 74 | + root.insert(BST(i, nums[i])) |
| 75 | + ret = [0] * len(nums) |
| 76 | + |
| 77 | + def _dfs(root): |
| 78 | + if not root: |
| 79 | + return ret |
| 80 | + ret[root.index] = root.count |
| 81 | + _dfs(root.left) |
| 82 | + _dfs(root.right) |
| 83 | + return ret |
| 84 | + |
| 85 | + return _dfs(root)[::-1] |
| 86 | + |
| 87 | + |
| 88 | +# print(Solution().countSmaller([5, 2, 6, 1])) |
| 89 | +# print(Solution().countSmaller([1, 2, 7, 8, 5])) |
| 90 | +# print(Solution().countSmaller([-1, -1])) |
0 commit comments