315. 计算右侧小于当前元素的个数
难度困难
给你一个整数数组 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源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))