LeetCode:315. 计算右侧小于当前元素的个数 分治(逆序对

本博客介绍如何使用分治算法解决LeetCode中的315题,即计算数组中每个元素右侧有多少个更小的元素。通过将数组一分为二,递归地寻找右侧的小于当前元素的个数,并结合有序序列的特性,类似逆序对问题进行优化。详细思路和代码实现均给出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

示例:
输入: [5,2,6,1]
输出: [2,1,1,0]

解释:
5 的右侧有 2 个更小的元素 (2 和 1).
2 的右侧仅有 1 个更小的元素 (1).
6 的右侧有 1 个更小的元素 (1).
1 的右侧有 0 个更小的元素.

链接

思路

这题可以使用分治思想:
设函数可以找到[l, r]内,每个数字,右边的比他小的数字个数
用mid将数组一分为二,那么对于下标 i (i<=mid),可以将问题分解为:

  • 在 [l, mid] 中找比 i 小的数
  • 在 [mid+1, r] 中找比 i 小的数

前者可以用递归解决,递归的同时对子数组排序,后者,在有序序列找两下标满足一定的大小关系,马上想到类比【逆序对问题

对于下标 i 范围:[l ~ mid],在 [mid+1, r] 向右中找第一个 j 使得 nums[j]>=nums[i],因为是升序,所以 mid+1 ~ j-1 下标的数字都小于 nums[i],那么nums[i]的答案可以 += j-(mid+1)

注意
对于 i,需要升序枚举,因为如果降序枚举 i,nums[i] 减小可能导致先前 j 增加而排除的答案再次可用,故应该从小到大升序枚举 i

代码

class Solution {
   
public:
    vector<int> ans;
    typedef struct p
    {
   
        int val, id;
        p():val(0),id
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值