首页 > 其他分享 >[LeetCode] 1365. How Many Numbers Are Smaller Than the Current Number 有多少小于当前数字的数字

[LeetCode] 1365. How Many Numbers Are Smaller Than the Current Number 有多少小于当前数字的数字

时间:2024-05-29 23:25:40浏览次数:29  
标签:cnt Smaller num 数字 nums int Many vector


Given the array nums, for each nums[i] find out how many numbers in the array are smaller than it. That is, for each nums[i] you have to count the number of valid j's such that j != i and nums[j] < nums[i].

Return the answer in an array.

Example 1:

Input: nums = [8,1,2,2,3]
Output: [4,0,1,1,3]
Explanation:
For nums[0]=8 there exist four smaller numbers than it (1, 2, 2 and 3).
For nums[1]=1 does not exist any smaller number than it.
For nums[2]=2 there exist one smaller number than it (1).
For nums[3]=2 there exist one smaller number than it (1).
For nums[4]=3 there exist three smaller numbers than it (1, 2 and 2).

Example 2:

Input: nums = [6,5,4,8]
Output: [2,1,0,3]

Example 3:

Input: nums = [7,7,7,7]
Output: [0,0,0,0]

Constraints:

  • 2 <= nums.length <= 500
  • 0 <= nums[i] <= 100

这道题说是给了一个数组 nums,让对于数组中的每一个数字,统计出数组中有多少个数小于该数字,并组成一个数组返回。参见题目中的例子不难理解题意,虽然说这是一道 Easy 的题,但是博主还是不想用 brute force 的方法,因为对于每个数字都遍历一遍数字统计小的实在是太直接了,完全不用什么思考,而且平方级的时间复杂度,也不知道 OJ 能不能放行。这道题比较好的解题思路是用时间换空间,建立每个数字与其出现次数之间的映射,同时按照数字大小排序,那么这里用 TreeMap 这个数据结构就比较合适了。这样按顺序遍历映射对儿,比当前映射对儿的数字小的数字个数就是前面所有映射对儿的值的总和,就拿题目中的例子1来举例吧,建立的映射对儿是:

1 -> 1
2 -> 2
3 -> 1
8 -> 1

这里定义个变量 cnt 表示当前已经累加的映射值,初始化为0。当遍历到第一个映射对儿的数字1时,当前的 cnt 值就是比1小的数字个数,为0,是对的,然后此时 cnt 要加上当前映射值1。再遍历到下一个映射对儿数字2,此时 cnt 是比2小的数字个数,为1,是对的,然后此时 cnt 要加上当前映射值2。以此类推,就可以知道比每个数字小的数字个数了,为了方便的保存结果,这里用一个 HashMap 来建立数字和比其小的数字个数之间的映射,最终组成返回数组 res 的时候就直接到这个 HashMap 中去取就可以了,参见代码如下:


解法一:

class Solution {
public:
    vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
        int cnt = 0;
        vector<int> res;
        map<int, int> cntMap;
        unordered_map<int, int> m;
        for (int num : nums) {
            ++cntMap[num];
        }
        for (auto a : cntMap) {
            m[a.first] = cnt;
            cnt += a.second;
        }
        for (int num : nums) {
            res.push_back(m[num]);
        }
        return res;
    }
};

当然我们也可以不用 TreeMap 和 HashMap,因为题目限定了数字的大小不超过 100,所以可以用一个大小为 101 的数字来代替 TreeMap,统计每个数字出现的个数。接下来是建立累加和数组,这样位置i上的数字 cnt[i] 就表示不小于数字i的数字个数,所以小于数字i的数字个数就是 cnt[i-1],有了累加和数字,就可以很方便的生成返回数组 res 了,参见代码如下:


解法二:

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

再来看一种利用二分搜索法的解法,关于二分搜索法可以参见博主之前的总结帖 LeetCode Binary Search Summary 二分搜索法小结,先将原数组排序,这样对于每个数字,查找第一个不小于该数字的位置,其坐标就是数组中小于该数字的个数,还是用例子1,来举例,排序后为 [1,2,2,3,8],对于数字3来说,第一个不小于3的数字的位置是3,同时也表示有3个数字比数字3小,参见代码如下:


解法三:

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

当然我们也可以利用 C++ 的自带函数 lower_bound 来进行二分搜索,这样就比较偷懒啦~


解法四:

class Solution {
public:
    vector<int> smallerNumbersThanCurrent(vector<int>& nums) {
        vector<int> res, t = nums;
        sort(t.begin(), t.end());
        for (int num : nums) {
            int cnt = lower_bound(t.begin(), t.end(), num) - t.begin();
            res.push_back(cnt);
        }
        return res;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1365


类似题目:

Count of Smaller Numbers After Self

Longest Subsequence With Limited Sum


参考资料:

https://leetcode.com/problems/how-many-numbers-are-smaller-than-the-current-number

https://leetcode.com/problems/how-many-numbers-are-smaller-than-the-current-number/solutions/524996/java-beats-100-o-n/


LeetCode All in One 题目讲解汇总(持续更新中...)

标签:cnt,Smaller,num,数字,nums,int,Many,vector
From: https://www.cnblogs.com/grandyang/p/18221326

相关文章

  • 【视频讲解】偏最小二乘结构方程模型PLS-SEM分析白茶产业数字化对共同富裕的影响
    全文链接:https://tecdat.cn/?p=36314原文出处:拓端数据部落公众号本文将通过视频讲解,展示如何用偏最小二乘结构方程模型PLS-SEM分析白茶产业数字化对共同富裕的影响,并结合Python用偏最小二乘回归PartialLeastSquares,PLS分析桃子近红外光谱数据可视化实例和R语言结构方程模型SEM......
  • Proteus8.0仿真应用设计(九十三)基于STM32CubeMX、STM32F103C8T6 、FREERTOS、MCP4151(SP
    一、简介:        MCP4151是一款SPI接口的7位数字电位器。二、主要特性:电阻值(欧姆)5kΩ、10kΩ、50kΩ、100kΩ抽头数257接口类型SPI通道数1供电电压1.8V~5.5V精度±20%温度系数(典型值)150ppm/℃工作温度-40℃~+125℃三、引脚定义:四、内部逻辑框图:五、时序图......
  • GEE C26 GEEDiT—Digitizing from Satellite Imagery从卫星影像数字化
     一、TheGoogleEarthEngineDigitisationTool(GEEDiT)  GEE数字化工具谷歌地球引擎数字化工具(GEEDiT)允许用户定义地球上任何地方的一个点,并通过一个简单的图形用户界面(GUI)对每个卫星的数据进行过滤,以获得用户定义的时间框架、最大可接受的云量,以及预定义或自定义图......
  • 基于TAE的数字钥匙自动化测试解决方案
    方案概述    在汽车发展和用户需求的推动下,汽车钥匙开始从传统的机械钥匙向数字化、智能化方向发展。目前常见的数字钥匙集成了蓝牙、NFC、UWB等技术实现了移动设备与车端的通信,可以帮助用户便捷的实现车辆功能控制。随着数字钥匙的广泛应用,相关的测试需求也进一步增加,人......
  • 在数字化时代,数据成为了一种重要资源
    随着科技的不断发展和数字经济的崛起,数字化和智能化已经成为了各行各业的趋势和必然选择。在计算机的发展过程中,数字化和智能化的革命极大地推进了计算机的发展,特别是在人工智能领域的发展中。在数字化时代,数据成为了一种重要的资源。数据在各行各业中发挥着越来越重要的作用......
  • 【EI检索稳定 | 东华理工大学机械与电子工程学院协办】2024年数字技术与智慧教育国际
    2024年数字技术与智慧教育国际会议(DTSE2024)将于2024年7月26日在广东省广州市召开,本次会议专注于“数字技术与智慧教育”领域,将汇集全球范围内的学者、研究人员以及教育技术开发者,共同探索和分享该领域内的最新学术成果和技术进展。会议的主要目标是构建一个高质量的学术交流和......
  • C语言猜数字游戏完整版
    题目:电脑随机生成1~100的随机数;玩家猜数字过程中,根据猜测数据的大小给出或多或少的反馈,直到猜对,游戏结束。首先,随机数的生成:①rand函数可以生成随机数,rand函数会返回一个伪随机数,这个随机数的范围是0~RANDMAX之间;②srand函数:用来初始化随机数的生成器;③time函数:在程序......
  • 数字信号处理实验三:IIR数字滤波器设计及软件实现
    一、实验目的1.掌握MATLAB中进行IIR模拟滤波器的设计的相关函数的应用;2.掌握MATLAB的工具箱中提供的常用IIR数字滤波器的设计函数的应用;3.掌握MATLAB的工具箱中提供的模拟滤波器转数字滤波器的相关的设计函数的应用。二、实验内容本实验为综合性实验项目,要求通过利用MAT......
  • 深度学习入门:3.手写数字分类
    这一章将基于Pytorch在只用全连接网络情况下实现手写数字识别,让大家基本了解怎么实现模型训练和预测使用。完整代码在最下面。一.MNIST数据集1.数据集介绍MNIST数据集包含60,000个训练样本和10,000个测试样本,每个样本都是28x28像素的灰度图像,表示一个0到9的手写......
  • WebGIS 智慧城市可视化合集 | 图扑数字孪生
    智慧城市可视化建设不仅提升了城市管理的科技含量和效率,还促进了城市可持续发展,提升了居民的生活质量。随着技术的不断发展和应用,智慧城市可视化建设将会更加丰富和完善,为城市发展带来更加广阔的前景。效果展示图扑应用自研HTforWeb产品搭建轻量化GIS智慧城市,一屏覆盖城市......