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

1. 采用归并排序计算逆序数组对的方法来计算右侧更小的元素 time O(nlogn);
计算逆序对可以采用两种思路:
a. 在左有序数组元素出列时计算右侧比该元素小的数字的数目为 cnt=r-mid-1; 右有序数组出列完成后cnt=end-mid;
b. 在右有序数组元素出列时计算左侧比该元素大的数字的数目为 cnt=mid-l+1; 左有序数组出列完成后cnt=0;
但是只有python 和java, 补充C++代码;
C++ code:
class Solution {
public:
void merge(vector<int>& nums, vector<int>& indexs,vector<int>& counts,int start, int mid, int end){
//在左有序数组出列时计算右有序数组中比当前数字小的
vector<int> tmps;//存储临时的index;
int l=start;
int r=mid+;
while(l<=mid && r<=end){
if(nums[indexs[l]]<=nums[indexs[r]]){
tmps.push_back(indexs[l]);
counts[indexs[l]]+=r-mid-;
l++;
}else{
tmps.push_back(indexs[r]);
r++;
}
}
while(l<=mid){
tmps.push_back(indexs[l]);
counts[indexs[l]]+=end-mid;
l++;
}
while(r<=end){
tmps.push_back(indexs[r]);
r++;
}
for(int i=;i<tmps.size();i++){
indexs[start+i]=tmps[i];
}
}
void mergesort(vector<int>& nums, vector<int>& indexs, vector<int>& counts,int start, int end){
if(start>=end) return;
int mid=start+(end-start)/;
mergesort(nums,indexs,counts,start,mid);
mergesort(nums,indexs,counts,mid+,end);
if(nums[indexs[mid]]>nums[indexs[mid+]])
merge(nums,indexs,counts,start,mid,end);
}
vector<int> countSmaller(vector<int>& nums) {
//归并排序计算 time nlogn
int len=nums.size();
vector<int> counts(len,);
vector<int> indexs(len,);
for(int i=;i<len;i++){
indexs[i]=i;
}
mergesort(nums,indexs,counts,,len-);
return counts;
}
};
可以采用一个全局的tmps临时数组而不是每次都中转;然后合并l<mid 与 (nums[indexs[l]]<=nums[indexs[r]]),简化代码如下:
class Solution {
public:
void merge(vector<int>& nums, vector<int>& indexs, vector<int>& counts, vector<int>& tmps, int start, int mid, int end){
int l=start;
int r=mid+;
for(int i=start;i<=end;i++){
if(r>end || ((l<=mid)&&(nums[indexs[l]]<=nums[indexs[r]]))){
tmps[i]=indexs[l];
counts[indexs[l]]+=r-mid-;
l++;
}else{
tmps[i]=indexs[r++];
}
}
for(int i=start;i<=end;i++){
indexs[i]=tmps[i];
}
}
void mergesort(vector<int>& nums, vector<int>& indexs, vector<int>& counts, vector<int>& tmps, int start, int end){
if(start>=end) return;
int mid=start+(end-start)/;
mergesort(nums,indexs,counts,tmps,start,mid);
mergesort(nums,indexs,counts,tmps,mid+,end);
merge(nums,indexs,counts,tmps,start,mid,end);
}
vector<int> countSmaller(vector<int>& nums) {
//可以借鉴利用归并排序统计逆序对数,
int len=nums.size();
if(len==) return {};
vector<int> indexs,counts,tmps;
for(int i=;i<len;i++){
indexs.push_back(i),counts.push_back(),tmps.push_back();
}
mergesort(nums,indexs,counts,tmps,,len-);
return counts;
}
};
2. 对O(n2)的暴力搜索进行改进:
倒序遍历,用一个数组sorted_nums记录当前元素右边的元素排序后的结果,每次用二分查找寻找新元素插入位置,并且得到right为counts的结果;
time O(n(n+logn))但是要比归并排序慢十倍,是因为vector插入元素的关系?
C++ code:
class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
//暴力搜索,但是是从末尾计算,且将计算过的数排序存储,便于使用二分查找;
vector<int> sorted_nums, res;
for(int i=nums.size()-;i>=;i--){
int left=;
int right=sorted_nums.size();//这样mid索引不会出界,因为mid总是小于sorted_nums的长度的
//寻找nums[i]插入的位置,即比nums[i]大得第一个元素的位置;
while(left<right){
int mid=left+(right-left)/;
if(sorted_nums[mid]>=nums[i]){
right=mid;
}else{
left=mid+;
}
}
res.push_back(right);
sorted_nums.insert(sorted_nums.begin()+right,nums[i]);
}
reverse(res.begin(),res.end());
return res;
}
};
leetcode315 计算右侧小于当前元素的个数的更多相关文章
- [Swift]LeetCode315. 计算右侧小于当前元素的个数 | Count of Smaller Numbers After Self
You are given an integer array nums and you have to return a new countsarray. The counts array has t ...
- Leetcode 315.计算右侧小于当前元素的个数
计算右侧小于当前元素的个数 给定一个整数数组 nums,按要求返回一个新数组 counts.数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元 ...
- Java实现 LeetCode 315 计算右侧小于当前元素的个数
315. 计算右侧小于当前元素的个数 给定一个整数数组 nums,按要求返回一个新数组 counts.数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i ...
- [Leetcode]315.计算右侧小于当前元素的个数 (6种方法)
链接 给定一个整数数组 nums,按要求返回一个新数组 counts.数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量. 示例: 输 ...
- 315 Count of Smaller Numbers After Self 计算右侧小于当前元素的个数
给定一个整型数组 nums,按要求返回一个新的 counts 数组.数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于nums[i] 的元素的数量.例子:给定 nu ...
- 萌新笔记——Cardinality Estimation算法学习(一)(了解基数计算的基本概念及回顾求字符串中不重复元素的个数的问题)
最近在菜鸟教程上自学redis.看到Redis HyperLogLog的时候,对"基数"以及其它一些没接触过(或者是忘了)的东西产生了好奇. 于是就去搜了"HyperLo ...
- Cardinality Estimation算法学习(一)(了解基数计算的基本概念及回顾求字符串中不重复元素的个数的问题)
最近在菜鸟教程上自学redis.看到Redis HyperLogLog的时候,对“基数”以及其它一些没接触过(或者是忘了)的东西产生了好奇. 于是就去搜了“HyperLogLog”,从而引出了Card ...
- [LeetCode] Count of Smaller Numbers After Self 计算后面较小数字的个数
You are given an integer array nums and you have to return a new counts array. The counts array has ...
- MATLAB 统计不同区间中元素的个数
使用 find 命令: x = :;%生成数组 k = find( x > & x < );%查找大于2小于5的元素的数组下标 size(k,) %统计的元素的个数
随机推荐
- 建立一个能持续处理的C/S网络程序
程序流程图: 代码演示: 服务器端: #include<WinSock2.h> #include<Windows.h> #include<stdio.h> #inc ...
- Python Memcached、Redis & RabbitMQ使用
一.Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的 ...
- 计划任务 at,cron
示例:每3小时echo和wall命令
- 【树形dp 思维题】HHHOJ#483. NOIP司马懿
要注意利用一些题目的特殊条件吧. 题目大意 有一颗$n$个点带点权$a_i$的树,$q$次询问树上是否存在长度为$l$的路径. $n,q,l\le 10^5,0 \le a_i \le 2$ 题目分析 ...
- ABC007D Small Multiple[最短路]
题意:求$K$的倍数中数位和的最小值. 一开始有一种思路:由于产生答案的数字可能非常大,不便枚举,考虑转化为构造一个数字可以有$x\mod k=0$.然后二分答案数位和,数位DP检验是否存在,但是由于 ...
- Python numpy.ZIP 安装问题
今天在python上安装numpy,按照网上教程,安装pip,然后命令行直接:pip install numpy .但是一直因为资源问题下载失败. 后来下载了一个numpy-1.11.2.zip 安 ...
- mysqldump 使用--tab=path参数时提示mysqldump: Got error: 1290: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement when executing 'SELECT INTO OUTFILE'
报错: [root@zedu test]# mysqldump -h127.0.0.1 -uroot -p --single-transaction --add-drop-database --tab ...
- linux系统常用命令(一)
管理 在UNIX/linux系统中,一切皆为文件:若非文件,则为进程.首先认识文件系统: linux文件系统 /var - 经常变化的(variable)文件,诸如日志或数据库等 /usr - 包含绝 ...
- postman 跟restsharp 模拟请求http
https://github.com/restsharp/RestSharp postman 生成的访问代码: 好用! Features Assemblies for .NET 4.5.2 and . ...
- ValseWebninar 报告汇总
ValseWebninar为计算机视觉.图像处理.模式识别与机器学习等研究领域内的华人青年学者提供深入学术交流的舞台. 20191218:基于视觉和常识的深度推理 主持人: 主讲人: 2019 ...