問題描述
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].
Example:
Given nums = [5, 2, 6, 1]
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.
Return the array [2, 1, 1, 0].
問題分析
是一道hard題,還是有點難度。
問題求某數字右邊比其小的數,可以看做求逆序數,用歸并排序的思路來做。參考了LeetCode Discuss。
歸并left和right數組時,當選擇left中的元素進行歸并時,right中已經選擇的元素個數即為比該元素小的,因此其逆序數應加相應個數。
網上還有做法提到Fenwick Tree的,但是我還沒看懂...弱哭...
AC代碼
class Solution(object):
def countSmaller(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
smaller = [0 for i in range(len(nums))]
self.sort(list(enumerate(nums)), smaller)
return smaller
def sort(self, enum, smaller):
mid = len(enum)/2
if not mid:
return enum
left, right = self.sort(enum[:mid], smaller), self.sort(enum[mid:], smaller)
p = q = 0
m, n = len(left), len(right)
while p < m or q < n:
if q == n or p < m and left[p][1] <= right[q][1]:
enum[p+q] = left[p]
smaller[left[p][0]] += q
p += 1
else:
enum[p+q] = right[q]
q += 1
return enum