315. 计算右侧小于当前元素的个数

labuladong 题解

难度困难

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

 

示例 1:

输入:nums = [5,2,6,1]
输出:[2,1,1,0] 
解释:
5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素

示例 2:

输入:nums = [-1]
输出:[0]

示例 3:

输入:nums = [-1,-1]
输出:[0,0]

 

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

 

 

 

问题 1:为什么引入索引数组
依然可以使用「归并排序」的「分而治之」的算法思想。接下来要解决的问题是如何知道「每一个元素的右边有多少个元素比自己小」,这一点就需要我们知道 当前归并回去的那个元素在输入数组里是哪一个元素。

一种可行的办法是:把「下标」和「数值」绑在一起进行归并排序,在一些编程语言中提供了 Tuple 和 Pair 这样的类可以实现,也可以自己创建一个类。

 

 

 

#
# @lc app=leetcode.cn id=315 lang=python3
#
# [315] 计算右侧小于当前元素的个数
#

# @lc code=start
from collections import defaultdict

class Solution:
    def __init__(self) -> None:
        self.res = []
    def countSmaller(self, nums: List[int]) -> List[int]:
        def merge(nums,aux,l,mid,r):
            i = l 
            j = mid 
            k = l
            while i < mid and j < r:
                if aux[i][0] <= aux[j][0]:
                    nums[k] = aux[i]
                    self.res[nums[k][1]] += j - mid
                    i+=1
                    k+=1
                else:
                    nums[k] = aux[j]
                    j+=1
                    k+=1

            while i < mid:
                nums[k] = aux[i]
                self.res[nums[k][1]] += j - mid
                i+=1
                k+=1
            while j < r:
                nums[k] = aux[j]
                j+=1
                k+=1
            aux[l:r] = nums[l:r] 

        def merge_and_sort(nums,aux,l,r):
            #print(l,r)
            if l >= r-1:
                return 
            mid = l + (r-l)//2
            merge_and_sort(nums,aux,l,mid)
            merge_and_sort(nums,aux,mid,r)
            merge(nums,aux,l,mid,r)



        self.res = [0] * len(nums)
        num_pairs = []
        for i in range(len(nums)):
            num_pairs.append((nums[i],i))
        aux = num_pairs.copy()
        merge_and_sort(num_pairs,aux,0,len(nums))    
        print(num_pairs)
        return self.res 
# @lc code=end

 

posted @ 2023-06-12 16:10  乐乐章  阅读(27)  评论(0编辑  收藏  举报