(数组) 1365. 有多少小于当前数字的数字 ——【Leetcode每日一题】

news2024/11/18 3:43:36

❓1365. 有多少小于当前数字的数字

难度:简单

给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。

换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != inums[j] < nums[i]

以数组形式返回答案。

示例 1:

输入:nums = [8,1,2,2,3]
输出:[4,0,1,1,3]
解释:
对于 nums[0]=8 存在四个比它小的数字:(1,2,2 和 3)。
对于 nums[1]=1 不存在比它小的数字。
对于 nums[2]=2 存在一个比它小的数字:(1)。
对于 nums[3]=2 存在一个比它小的数字:(1)。
对于 nums[4]=3 存在三个比它小的数字:(1,2 和 2)。

示例 2:

输入:nums = [6,5,4,8]
输出:[2,1,0,3]

示例 3:

输入:nums = [7,7,7,7]
输出:[0,0,0,0]

提示

  • 2 < = n u m s . l e n g t h < = 500 2 <= nums.length <= 500 2<=nums.length<=500
  • 0 < = n u m s [ i ] < = 100 0 <= nums[i] <= 100 0<=nums[i]<=100

💡思路:

两层 for 循环暴力查找,时间复杂度明显为 O ( n 2 ) O(n^2) O(n2)。这里不做介绍,我们来看一下如何优化。

法一:排序

首先要找小于当前数字的数字,那么从小到大排序之后,该数字之前的数字就都是比它小的了。

  • 所以可以定义一个新数组 temp ,将数组排个序,排序之后,其实每一个数值的下标就代表这前面有几个比它小的了;
  • 然后在遍历原数组 nums 是,对每一个 num[i]temp 使用二分查找,查到每个元素第一个位置的下标,即为 比它小的所有数字的数目

法二: 计数排序

注意到数组元素的值域为 [0,100],所以可以考虑建立一个频次数组 cntcnt[i] 表示数字 i 出现的次数。

那么对于数字 i 而言,小于它的数目就为 cnt[0...i−1] 的总和。

🍁代码:(Java、C++)

法一:排序
Java

class Solution {
    public int[] smallerNumbersThanCurrent(int[] nums) {
        int n = nums.length;
        int[] temp = Arrays.copyOf(nums, nums.length);
        Arrays.sort(temp);
        int[] ans = new int[nums.length];
        for(int i = 0; i < n; i++){
            int left = 0, right = n - 1;
            while(left <= right){
                int mid = left + (right - left) / 2;
                if(temp[mid] >= nums[i]) right--;
                else left++;
            }
            ans[i] = right + 1;
        }
        return ans;
    }
}

C++

class Solution {
public:
    vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
        int n = nums.size();
        vector<int> temp(nums), ans(n);
        sort(temp.begin(), temp.end());
        for(int i = 0; i < n; i++){
            int left = 0, right = n - 1;
            while(left <= right){
                int mid = left + (right - left) / 2;
                if(temp[mid] >= nums[i]) right--;
                else left++;
            }
            ans[i] = right + 1;
        }
        return ans;
    }
};

法二: 计数排序
Java

class Solution {
    public int[] smallerNumbersThanCurrent(int[] nums) {
        int n = nums.length;
        int[] cnt = new int[101];
        int[] ans = new int[n];
        for(int num : nums){
            cnt[num]++;
        }
        int sum = 0;
        for(int i = 0; i <= 100; i++){
            if(cnt[i] != 0){
                sum += cnt[i];
                cnt[i] = sum - cnt[i];
            }
        }
        for(int i = 0; i < n; i++){
            ans[i] = cnt[nums[i]];
        }
        return ans;
    }
}

C++

class Solution {
public:
    vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
        int n = nums.size();
        vector<int> cnt(101, 0), ans(n);
        for(int num : nums){
            cnt[num]++;
        }
        int sum = 0;
        for(int i = 0; i <= 100; i++){
            if(cnt[i] != 0){
                sum += cnt[i];
                cnt[i] = sum - cnt[i];
            }
        }
        for(int i = 0; i < n; i++){
            ans[i] = cnt[nums[i]];
        }
        return ans;
    }
};

🚀 运行结果:

在这里插入图片描述

🕔 复杂度分析:

法一:排序

  • 时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn),其中 n 为数组的长度,排序需要 O ( n l o g n ) O(nlogn) O(nlogn) 的时间,随后需要 O ( n ) O(n) O(n) 时间来遍历 乘上 二分查找的时间 O ( l o g n ) O(logn) O(logn) ,所以总时间为 O ( n l o g n ) O(nlogn) O(nlogn)
  • 空间复杂度 O ( n ) O(n) O(n),因为要额外开辟一个数组。

法二: 计数排序

  • 时间复杂度 O ( n + k ) O(n + k) O(n+k),其中 k 为值域大小。需要遍历两次原数组,同时遍历一次频次数组 cnt 找出前缀和。。
  • 空间复杂度 O ( k ) O(k) O(k),因为要额外开辟一个值域大小的数组。

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!

注: 如有不足,欢迎指正!

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

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

相关文章

希捷科技:具有周期性价值的全球云存储之王

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结&#xff1a; &#xff08;1&#xff09;根据Statista的数据&#xff0c;希捷科技是全球硬盘驱动器市场的领导者&#xff0c;在全球拥有约43%的市场份额。 &#xff08;2&#xff09;希捷科技的管理层近期已经宣布了一…

Node.js模块化学习笔记

Node.js模块化 模块化雨模块 将一个复杂的程序文件依据一定规则&#xff08;规范&#xff09;拆分成多个文件的过程称之为模块化。 其中拆分的每个文件就是一个模块&#xff0c;模块的内部数据是私有的&#xff0c;不过模块可以暴露内部数据以便其他模块使用 模块化项目 编…

Python课期末考试复习

简答 定义函数的规则 1、函数代码块以def关键词开头&#xff0c;后接函数标识符名称和圆括号() 2、任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。 3、函数的第一行语句可以选择性的使用文档字符串用于存放函数说明。 4、函数内容以冒号起始&#xf…

从前序与中序遍历序列构造二叉树

题目链接 从前序与中序遍历序列构造二叉树 题目描述 注意点 inorder.length preorder.lengthpreorder 和 inorder 均 无重复 元素inorder 均出现在 preorderpreorder 保证 为二叉树的前序遍历序列inorder 保证 为二叉树的中序遍历序列 解答思路 前序遍历的首个节点为根节…

[架构之路-211]- 需求- 软架构前的需求理解:ADMEMS标准化、有序化、结构化、层次化需求矩阵 =》需求框架

目录 前言&#xff1a; 一、什么是ADMES: 首先&#xff0c;需求是分层次的&#xff1a; 其次&#xff0c;需求是有结构的&#xff0c;有维度的 再次&#xff0c;不同层次需求、不同维度需求之间可以相互转化&#xff08;难点、经验积累&#xff09; 最终&#xff0c;标准…

UnitTest 学习

UnitTest 一、UnitTest 基本使用1. TestCase 测试用例2. TestSuite 和 TestRunner3. TestLoader 测试加载4. Fixture 二、断言与参数化断言参数化 三、测试报告获取项目的绝对路径登录案例跳过 一、UnitTest 基本使用 UnItTest 框架介绍 UnitTest是python自带的一个单元测试框…

HTTP 和 HTTPS 协议原理【网络基础】

文章目录 1. HTTP 的优点2. HTTP 的缺点明文可能会被窃听通信方可能被伪装报文可能被篡改 2.1 弥补 HTTP 的缺点&#xff08;概述&#xff09;加密明文通信加密内容加密 验证通信方报文完整性校验 3. HTTPS 协议3.1 SSL/TLS 协议概述3.2 加密机制对称加密非对称加密混合加密 3.…

一文终结SQL 子查询优化

概要 子查询&#xff08;Subquery&#xff09;的优化一直以来都是 SQL 查询优化中的难点之一。关联子查询的基本执行方式类似于 Nested-Loop&#xff0c;但是这种执行方式的效率常常低到难以忍受。当数据量稍大时&#xff0c;必须在优化器中对其进行去关联化&#xff08;Decoor…

深入理解深度学习——Transformer:基础知识

分类目录&#xff1a;《深入理解深度学习》总目录 相关文章&#xff1a; 作为当下最先进的深度学习架构之一&#xff0c;Transformer被广泛应用于自然语言处理领域。它不单替代了以前流行的循环神经网络(recurrent neural network, RNN)和长短期记忆(long short-term memory, …

网络安全入门学习第十七课——PHP数组

文章目录 一、索引数组二、关联数组三、数组定义1、多维数组2、赋值方式3、短数组定义法&#xff08;[ ] PHP 5.4起增加的) 四、访问数组五、遍历数组1、使用 for 循环2、foreach语句遍历 六、合并两个数组1、“”联合运算符2、array_combine 函数 七、数组排序函数八、数组增删…

redis 全系列目录

redis常用资源_存在,及合理的博客-CSDN博客Redis 官网 推荐CRUG网站redis 中文 官网Spring Data Redis 客户端工具官网Distributed Locks with Redis | Redishttps://github.com/redisson/redisson 分布式锁实现大数据高并发Redis一本通-张文亮编著-微信读书 书籍推荐https://b…

Misc(三)

LSB 这题没见过&#xff0c;是看的wp 首先了解LSB是什么 LSB简介 最低有效位&#xff08; least significant bit&#xff0c;LSB&#xff09;指的是一个二进制数字中的最低位。最低有效位和最高有效位是相对应的概念。LSB是一种常被用做图片隐写的算法。LSB属于空域算法中的一…

学成在线----day6

1、断点续传 断点续传指的是在下载或上传时&#xff0c;将下载或上传任务&#xff08;一个文件或一个压缩包&#xff09;人为的划分为几个部分&#xff0c;每一个部分采用一个线程进行上传或下载&#xff0c;如果碰到网络故障&#xff0c;可以从已经上传或下载的部分开始继续上…

【文生图系列】Stable Diffusion原理篇

文章目录 Stable Diffusion的组成什么是扩散扩散是如何工作的去噪声绘制图像将文本信息添加到图像生成器中参考 “文生图”&#xff0c;或者AI绘画&#xff0c;最近异常火爆&#xff0c;输入一些描述性的语句&#xff0c;AI就能够生成相应的画作。甚至引发了一个问题&#xff1…

智能饮品柜颠覆升级,点赋科技引领行业跨越式发展

智能科技的迅速发展&#xff0c;不断改变人们的生活方式和商业模式&#xff0c;在众多领域迎来了新的机会和挑战。其中&#xff0c;饮品行业聚集了大量的消费者和商家&#xff0c;成为了一个具有广泛发展空间和潜力的市场。而在这个市场上&#xff0c;点赋科技认为智能饮品柜作…

ARM基础(3):MPU内存保护单元详解及例子

MPU(Memory Protection Unit)是ARM处理器中的一个特性&#xff0c;它提供了内存保护和访问控制的功能&#xff0c;通常用于实现操作系统的内存隔离和保护。比如我们可以设置所有的RAM为不可执行&#xff0c;这样就可以避免代码注入攻击。最近做项目过程中&#xff0c;使用的几个…

深度研究微软的资产负债表和财务状况以及未来投资价值

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 微软股票的关键指标 猛兽财经认为&#xff0c;微软公布的2023财年第三季度财务业绩&#xff0c;有三个关键指标值得投资者关注。 第一个关键指标是利息收入。微软的利息收入目前已经同比增长了44%&#xff0c;从2022财年第…

【Kubernetes存储篇】常见存储方案及场景分析

文章目录 一、持久化存储理论1、为什么要做数据持久化存储&#xff1f;2、常见持久化存储方案 二、案例&#xff1a;持久化存储方案1、emptydir临时存储卷2、hostPath本地存储卷3、NFS网络共享存储卷 一、持久化存储理论 官方中文参考文档&#xff1a; 1、为什么要做数据持久…

【三、网络配置与系统管理】

1 网络配置 ifconfig 显示网络接口的配置信息 [rootredis100 ~]# ifconfig ens33: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.10.100 netmask 255.255.255.0 broadcast 192.168.10.255inet6 fe80::f5c3:6a96:fe05:1965 prefixlen 64 scop…

该怎么学Python?自学Python的方法和资料整理!

导语 Python 作为一门简洁、易学且功能强大的编程语言&#xff0c;备受程序员和初学者的喜爱。如果你也想学习 Python&#xff0c;但不知从何入手&#xff0c;本文将为你整理一些自学 Python 的方法&#xff0c;助你快速入门并掌握这门语言。 为什么学习Python&#xff1f;&a…