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 @   乐乐章  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
历史上的今天:
2022-06-12 472. 连接词(trie)
2018-06-12 134. 加油站
2018-06-12 187. Repeated DNA Sequences(建立词典,遍历一遍 o(n))
点击右上角即可分享
微信分享提示