315. Count of Smaller Numbers After Self
You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].
Merge Sort
def countSmaller(self, nums: List[int]) -> List[int]:
res = [0] * len(nums)
array = list(zip(nums, range(len(nums))))
def mergeSort(arr, left, right):
if left == right:
return
mid = left + (right - left) // 2
mergeSort(arr, left, mid)
mergeSort(arr, mid + 1, right)
merge(arr, left, mid, right)
def merge(arr, left, mid, right):
i = left
j = mid + 1
tmp = []
while i <= mid or j <= right:
if j > right or (i <= mid and arr[i][0] <= arr[j][0]):
tmp.append(arr[i])
res[arr[i][1]] += j - mid - 1
i += 1
else:
tmp.append(arr[j])
j += 1
arr[left:right + 1] = tmp
mergeSort(array, 0, len(nums) - 1)
return res
Segment Tree
def countSmaller(self, nums: List[int]) -> List[int]:
# implement segment tree
def update(index, value, tree, size):
index += size # shift the index to the leaf
# update from leaf to root
tree[index] += value
while index > 1:
index //= 2
tree[index] = tree[index * 2] + tree[index * 2 + 1]
def query(left, right, tree, size):
# return sum of [left, right)
result = 0
left += size # shift the index to the leaf
right += size
while left < right:
# if left is a right node
# bring the value and move to parent's right node
if left % 2 == 1:
result += tree[left]
left += 1
# else directly move to parent
left //= 2
# if right is a right node
# bring the value of the left node and move to parent
if right % 2 == 1:
right -= 1
result += tree[right]
# else directly move to parent
right //= 2
return result
offset = 10**4 # offset negative to non-negative
size = 2 * 10**4 + 1 # total possible values in nums
tree = [0] * (2 * size)
result = []
for num in reversed(nums):
smaller_count = query(0, num + offset, tree, size)
result.append(smaller_count)
update(num + offset, 1, tree, size)
return reversed(result)
Binary Index Tree
def countSmaller(self, nums: List[int]) -> List[int]:
# implement Binary Index Tree
def update(index, value, tree, size):
index += 1 # index in BIT is 1 more than the original index
while index < size:
tree[index] += value
index += index & -index
def query(index, tree):
# return sum of [0, index)
result = 0
while index >= 1:
result += tree[index]
index -= index & -index
return result
offset = 10**4 # offset negative to non-negative
size = 2 * 10**4 + 2 # total possible values in nums plus one dummy
tree = [0] * size
result = []
for num in reversed(nums):
smaller_count = query(num + offset, tree)
result.append(smaller_count)
update(num + offset, 1, tree, size)
return reversed(result)