计数排序(转载)

本文介绍了计数排序算法的工作原理及其实现过程。该算法适用于正整数数据集,通过使用数轴来记录每个数值的出现频率并确定其位置,从而实现高效排序。
今天下午研究了下CountingSort算法,虽然这个算法的效率为O(n),简单测试了一下,确实蛮快的。但是这个算法的限制太多:

数据集必须为正整数。。。(也就是说数据集中不能有负数和小数,连0都不行!!) 因此这个算法的应用范围很小,不过速度确实很快。其实网上已经有很多示例了,不过看和自己写一个示例感觉是完全不一样的,呵呵。。。



问:为什么这个算法能不比较就知道数值的位置呢?
答:因为这个算法引入了”数轴“的概念,”数轴“的作用相当于是一个计数器,记录了每个数值出现的频率,
”数轴“的大小应该为数据集中的最大值,以数据集中的数值作为索引(因此,前提条件是数据集必须都是正整数)
如在数组{1,2,3,4,5,4},”数轴“的大小应该为5 , 具体内容为:{1,1,1,2,1}
然后再计算数据集中的每个数值的位置:其实就是累加”数轴“ 累加后的结果为:{1,2,3,5,6}
因为”数轴“是有序的,因此,可以由”数轴“告诉你数据集中每个数值的位置,如:数值 3在整个数据集的第3位,直接插入即可。
这下明白了吧,关键就是”数轴“是有序的。
这段代码是用来解决“最少数量的箭引爆气球”这个问题的经典算法实现。下面我会详细介绍它的功能和工作原理: ### 功能概述 给定一系列二维平面上表示气球位置的区间(即每一个气球对应一段水平线段),目标是找到最少的数量的垂直箭能够射爆所有的气球。 ### 代码分析 #### 1. **类及函数声明** ```cpp class Solution { public: int findMinArrowShots(vector<vector<int>>& points); }; ``` - 这里定义了一个名为Solution的类,其中包含公共成员函数findMinArrowShots。 - 此函数接收一个参数`points`,这是一个存储了多个气球区间的二维向量。 #### 2. **排序步骤** ```cpp ranges::sort(points, {}, [](auto& p) { return p[1]; }); // 按照右端点从小到大排序 ``` - 调用了C++20引入的新特性`std::ranges::sort`来对`points`进行排序。 - 排序基于每个气球区间的结束坐标(p[1]),使得数组按照这些坐标的递增次序排列。 #### 3. **初始化计数变量和前驱标记** ```cpp int ans = 0; // 计算所需最小箭矢数目 long long pre = LLONG_MIN; // 初始设置为不可能达到的小值 ``` - `ans`: 初始化为零,用来记录需要多少支箭才能击破全部气球。 - `pre`: 首先设定成非常小的一个数字(`LLONG_MIN`),以便后续比较时可以保证第一次循环一定能满足条件更新它。 #### 4. **遍历并计算最少箭数** ```cpp for (auto& p : points){ if (p[0] > pre){ // 当当前气球开始位置大于上一支箭的位置,则增加箭的数量 ans++; pre = p[1]; // 更新新的箭头放置在当前气球结尾处 } } ``` - 循环检查每个气球是否能被之前的一支箭射中。 - 条件判断:如果当前气球起始位置超过上次射击范围(pre),则需新增一只箭(即`ans++`)并将此新箭设于现气体球末端作为下次参照基准。 #### 5. **返回结果** ```cpp return ans; ``` 最后返回总所需的最少箭数量。 --- ### 示例说明 假设输入如下: ```txt [[10,16],[2,8],[1,6],[7,12]] ``` 经过上述过程处理后得到的结果将是: ```txt 2 ``` 解释:你可以分别从x=6 和 x=11两个地方发射两枚箭即可覆盖所有气球区域。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值