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

news2025/5/25 21:49:19

题目链接

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

题目描述

注意点

  • counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量

解答思路

  • 本题是交易逆序对的总数的扩展,可以先进入交易逆序对的总数了解,本题与交易逆序对的总数的区别在于需要记录每个元素对逆序对的贡献
  • 第一个思路是桶排序,从后往前遍历数组,将数组中的元素放进对应桶中,遍历到某个元素时,根据前缀和计算其右侧小于该元素的个数。但是桶排序要求元素最好在某个较小的区间内,否则需要创建大量空间作为桶,所以还需要提前将数组去重后对每个数字取新的映射,保证其处于某段连续的空间内,使用桶排序时如果有大量相同的元素时间比较快,如果数字比较分散则时间复杂度并不理想
  • 另一个思路是归并排序,为了方便记录每个元素对逆序对的贡献,创建一个数据结构Pointer同时存储元素值和右侧小于当前元素的个数,在归并排序时,找到右区间比Pointer.val小的元素,更新Pointer.smallerCount。需要注意的是,每次更新Pointer.smallerCount时,其增长量并不是1,而是右区间所以比其小的元素的总数,也就是找到右区间第一个比左区间当前元素大的元素后右区间此刻的指针相较于初始位置移动的距离

代码

方法一:

class Solution {
    public List<Integer> countSmaller(int[] nums) {
        List<Integer> res = new ArrayList<>(nums.length);
        // 去重
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
            set.add(num);
        }
        int n = set.size();
        // 排序
        int index = 0;
        int[] uniqueNums = new int[n];
        for (int num : set) {
            uniqueNums[index] = num;
            index++;
        }
        Arrays.sort(uniqueNums);
        // 哈希表映射,key->实际值,value->排序后所处的数组下标
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            map.put(uniqueNums[i], i);
        }
        int[] smallerArr = new int[nums.length];
        int[] barrelArr = new int[n];
        for (int i = nums.length - 1; i >= 0; i--) {
            int barrelIdx = map.get(nums[i]);
            barrelArr[barrelIdx] += 1;
            int smallerSum = 0;
            for (int j = 0; j < barrelIdx; j++) {
                smallerSum += barrelArr[j];
            }
            smallerArr[i] = smallerSum;
        }
        for (int num : smallerArr) {
            res.add(num);
        }
        return res;
    }
}

方法二:

class Solution {
    public List<Integer> countSmaller(int[] nums) {
        int n = nums.length;
        Pointer[] pointerArr = new Pointer[n];
        for (int i = 0; i < n; i++) {
            Pointer pointer = new Pointer();
            pointer.val = nums[i];
            pointer.smallerCount = 0;
            pointerArr[i] = pointer;
        }
        mergeSort(pointerArr, 0, n - 1);
        List<Integer> res = new ArrayList<>(n);
        for (Pointer pointer : pointerArr) {
            res.add(pointer.smallerCount);
        }
        return res;
    }

    public Pointer[] mergeSort(Pointer[] pointerArr, int left, int right) {
        if (left > right) {
            return null;
        }
        if (left == right) {
            return new Pointer[] {pointerArr[left]};
        }
        int mid = (left + right) / 2;
        int len = right - left + 1;
        Pointer[] leftArr = mergeSort(pointerArr, left, mid);
        Pointer[] rightArr = mergeSort(pointerArr, mid + 1, right);
        Pointer[] mergeArr = new Pointer[len];
        int leftIdx = 0, rightIdx = 0;
        while (leftIdx < leftArr.length || rightIdx < rightArr.length) {
            // 左区间已遍历完,右区间数组后续值都比左区间大
            if (leftIdx >= leftArr.length) {
                mergeArr[leftIdx + rightIdx] = rightArr[rightIdx++];
                continue;
            }
            // 找到左区间比右区间哪些数更大
            while (rightIdx < rightArr.length && leftArr[leftIdx].val > rightArr[rightIdx].val) {
                mergeArr[leftIdx + rightIdx] = rightArr[rightIdx++];
            }
            leftArr[leftIdx].smallerCount += rightIdx;
            mergeArr[leftIdx + rightIdx] = leftArr[leftIdx++];
        }
        return mergeArr;
    }
}

class Pointer {
    public int val;
    public int smallerCount;
}

关键点

  • 桶排序的思想
  • 前缀和的思想
  • 归并排序的思想
  • 使用更加灵活的数据结构存储数据以节省时间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1355748.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

macOS跨进程通信: XPC 创建实例

一&#xff1a;简介 XPC 是 macOS 里苹果官方比较推荐和安全的的进程间通信机制。 集成流程简单&#xff0c;但是比较绕。 主要需要集成 XPC Server 这个模块&#xff0c;这个模块最终会被 apple 的根进程 launchd 管理和以独立进程的方法唤起和关闭&#xff0c; 我们主app 进…

mysql忘记密码的三种解决方案

1、修改密码的三种方式 mysql用户分为root用户&#xff08;超级管理员&#xff0c;拥有所有权限&#xff09;和普通用户&#xff0c;mysql服务器通过权限表来控制用户对数据库的访问,这些权限表存于root用户下的mysql数据库中。 在使用mysql数据库过程中&#xff0c;往往需要…

DevOps(6)

目录 26.如何在Linux下跨不同的虚拟桌面共享程序&#xff1f; 27.无名&#xff08;空&#xff09;目录代表什么&#xff1f; 29.什么是守护进程&#xff1f; 30.如何从一个桌面环境切换到另一个桌面环境&#xff0c;例如从KDE切换到Gnome? 26.如何在Linux下跨不同的虚拟桌面…

excel中找出重复项,并标红

一、查找重复值 二、清除格式 还是通过添加规则的路径&#xff0c;清除格式&#xff0c;直接通过格式刷&#xff0c;刷不掉。

服务器为什么大多用 Linux?

服务器为什么大多用 Linux&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「Linux的资料从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&#xff01;&#…

AntDB内存管理之内存上下文

1. 主题说明 AntDB的内存管理在开发时&#xff0c;使用了内存上下文机制来实现内存管理。本文就从AntDB的内存上下文机制出发&#xff0c;解析内存上下文的实现原理。AntDB的代码中&#xff0c;涉及到内存的处理时&#xff0c;经常会看到下面这样的代码。 图1&#xff1a;切换…

msyql迁移到人大金仓数据库

1&#xff0c;点击数据迁移工具 2&#xff0c;在浏览器上输入http://localhost:54523&#xff0c;默认账号和密码为kingbase,kingbase&#xff0c;进入之后&#xff0c;就是项目的页面 3&#xff0c;数据库管理 添加源数据库&#xff0c;点击确定就可以了&#xff0c;也可以测…

鸿蒙问题之本地模拟器无法识别

今天按例打开本地模拟器&#xff0c;发现DevEco Studio不能检测到我的本地模拟器了。 重启了DevEco Studio和模拟器多次都无果。果断删除模拟器 然后创建一个新的&#xff0c;就可以成功检测到了。这应该是idea的一个bug

反编译会遇到哪些难题

反编译是把已编译的程序代码还原成源代码的过程&#xff0c;是软件逆向工程中重要的一环。反编译可以帮助开发者快速理解和修改已有的程序&#xff0c;也可以帮助安全专家发现程序中的漏洞。但是反编译也存在许多挑战和难题。下面简单的从几个方面了解一下反编译会遇到的难题。…

【Nodejs】基于Promise异步处理的博客demo代码实现

目录 package.json www.js db.js app.js routes/blog.js controllers/blog.js mysql.js responseModel.js 无开发&#xff0c;不安全。 这个demo项目实现了用Promise异步处理http的GET和POST请求&#xff0c;通过mysql的api实现了博客增删改查功能&#xff0c;但因没有…

VR云游开启智慧旅游新纪元,打造“云旅游”新模式

元旦假期&#xff0c;全国文化和旅游市场平稳有序&#xff0c;家人和亲友的出游趋势稳步增加&#xff0c;演唱会、音乐节、跨年等活动的叠加让元旦出游更加吸引游客。在冰雪旅游热度持续攀升的时候&#xff0c;许多年轻群体已经开始使用VR云游进行智慧景区旅游&#xff0c;身临…

作业--day41

利用模板类完成顺序表 #include <iostream>using namespace std;//模板类 template <typename T> class SeqTab{T arr[20];int maxsize; public:SeqTab():maxsize(0){}void Insert(T a);void Search(T a);void Delete(int index);void Show(); };//尾插 template …

bullet3 三种碰撞检测及实现

Bullet 物理引擎是一个专业的开放源码的碰撞检测&#xff0c;刚体和柔体动力学库。Bullet 物理引擎目标是实时和交互使用在游戏&#xff0c;电影和机器人的视觉效果。自由zlib授权的商业使用库。 bullet3的三种碰撞检测 以下三种方式都是可以达到碰撞检测的效果&#xff1a; …

新能源汽车@2023/24:卷价格、拼智能与生态战

【潮汐商业评论/原创】 2023年末尾&#xff0c;受到大众广泛热议的小米汽车发布会“姗姗来迟”&#xff0c;也为“乱战”中的2023新能源汽车市场画上了一个句号。 然而&#xff0c;在雷军整整三个小时看似平和的演讲与技术讲解中&#xff0c;实则在电机、智驾、智舱等核心技术…

多元线性回归案例--客户价值模型

文章目录 step 1&#xff1a;读取数据step 2&#xff1a;搭建模型step 3&#xff1a;构造回归方程step 4&#xff1a;评估模型 利用多元线性回归模型可以根据多个因素来预测客户价值&#xff0c;当模型搭建完成后&#xff0c;便可对不同价值的客户采用不同的业务策略。 这里以信…

C#高级语法 Attribute特性详解和类型,方法,变量附加特性讲解

文章目录 前言相关资料Attribute特性个人原理理解特性的声明与使用类型特性运行结果&#xff1a; 找到类的Attribute属性方法特性和变量特性代码封装测试类TestService1TestService2TestService3 测试代码运行结果 对封装的代码进行优化封装代码测试代码运行结果&#xff08;和…

雾天条件下 SLS 融合网络的三维目标检测

论文地址&#xff1a;3D Object Detection with SLS-Fusion Network in Foggy Weather Conditions 论文代码&#xff1a;https://github.com/maiminh1996/SLS-Fusion 论文摘要 摄像头或激光雷达&#xff08;光检测和测距&#xff09;等传感器的作用对于自动驾驶汽车的环境意识…

3D 纹理的综合指南

在线工具推荐&#xff1a;3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 我们经常看到超现实主义的视频游戏和动画电影角色出现在屏幕上。他们皮肤上的…

在win10上cuda12+tensorrt8.6+vs2019环境下编译paddle2.6生成python包与c++推理库

paddle infer官方目前没有发布基于cuda12的c库&#xff0c;为此参考https://www.paddlepaddle.org.cn/inference/user_guides/source_compile.html实现cuda12的编译安装&#xff0c;不料博主才边缘好自己的paddle2.6&#xff0c;paddle官方已经发布了cuda12.0的paddle2.6框架。…

嵌入式MCU:如何安装codeWarrior 和Jlink

先安装codeWarrior 15.0版本,这个官网上没有这个版本要去blazar的这个网站上下载: Blazar-α系统电路图纸(MOOC课程对应)(Updating)-Blazar开源硬件与MOOC codeWarrior 安装不要安装在中文路径里面 安装完了codeWarrior 再安装Jlink 然后再装Jlink 这个也是从上面的…