Approach
Sorting and greedy selection
For Count of Smaller Numbers After Self, the implementation first exposes a useful order, then scans that order while making locally justified choices.
- Choose the key that reveals the greedy or grouping structure.
- Sort the relevant records by that key.
- Scan in order, maintaining the invariant that makes each local choice safe.
Code notes
- 41 lines of Python from the credited upstream file 315.py.
- The implementation visibly relies on sequence storage, hash lookup, ordered lookup.
- No explicit loop blocks detected.
Complexity
Sorting is typically the dominant term unless the subsequent scan uses a more expensive nested operation.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class FenwickTree:2 def __init__(self, n: int):3 self.sums = [0] * (n + 1)4 5 def add(self, i: int, delta: int) -> None:6 while i < len(self.sums):7 self.sums[i] += delta8 i += FenwickTree.lowbit(i)9 10 def get(self, i: int) -> int:11 summ = 012 while i > 0:13 summ += self.sums[i]14 i -= FenwickTree.lowbit(i)15 return summ16 17 @staticmethod18 def lowbit(i: int) -> int:19 return i & -i20 21 22class Solution:23 def countSmaller(self, nums: list[int]) -> list[int]:24 ans = []25 ranks = self._getRanks(nums)26 tree = FenwickTree(len(ranks))27 28 for num in reversed(nums):29 ans.append(tree.get(ranks[num] - 1))30 tree.add(ranks[num], 1)31 32 return ans[::-1]33 34 def _getRanks(self, nums: list[int]) -> dict[int, int]:35 ranks = collections.Counter()36 rank = 037 for num in sorted(set(nums)):38 rank += 139 ranks[num] = rank40 return ranks41