You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].

Example 1:

Input: nums = [5,2,6,1]
Output: [2,1,1,0]
Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.

Constraints:

  • 0 <= nums.length <= 10^5
  • -10^4 <= nums[i] <= 10^4
 
class Solution {
public:
vector<int> countSmaller(vector<int>& nums) {
vector<int> res(nums.size(),0);
//从右向左,将数组有序插入tmp.利用二分查找确定当前数右边比它小的数的个数
vector<int> tmp;
for(int i=nums.size()-1;i>=0;i--){
int left = 0,right=tmp.size()-1;
//找第一个大于等于当前数的位置。插入其中
while(left <= right){
int mid = left+(right-left)/2;
if(tmp[mid] < nums[i]) left = mid+1;
else right = mid-1;
}
//最后返回的位置是left
res[i]=left;
//插入nums[i]
tmp.insert(tmp.begin()+left,nums[i]);
}
return res;
}
};

//归并:先引入逆序数;不同于逆序数对:

res[nums[i].second] += (j-mid-1);
这个里面坑比较多
class Solution {
public:
//法二:利用归并排序求逆序对数的方法
//https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/submissions/ vector<int> countSmaller(vector<int>& nums) {
int n=nums.size();
vector<int> res(n,0);
if(n==0 || n==1) return res;
vector<pair<int,int>> tmp(n,pair<int,int>{0,0});
vector<pair<int,int>> idx;
for(int i=0;i<n;i++){
idx.push_back(make_pair(nums[i],i));
}
mergesort(idx,tmp,0,n-1,res);
return res;
} //merge的过程将left到right有序重新存入nums.归并nums[left,mid],nums[mid+1,right]
void merge(vector<pair<int,int>>& nums,vector<pair<int,int>>& tmp,int left,int mid,int right,vector<int>& res) {
int i=left,j=mid+1,k=left;
for(;i<=mid&&j<=right;){
if(nums[i].first<=nums[j].first){
//不同于算整个数组逆序数
//这里的i不是之前的i。归并后数字的位置被改变了.所以利用pari记录nums[i]原始位置
//res[i] += (j-mid-1);
res[nums[i].second] += (j-mid-1);
tmp[k++] = nums[i++];
}else{
tmp[k++] = nums[j++];
}
}
//还有未归并完成的
while(i<=mid){
//先计算res
res[nums[i].second] += (j-mid-1);
tmp[k++]=nums[i++];
}
while(j<=right){
tmp[k++]=nums[j++];
}
//将tmp重新放入nums,那么nums[left,right]即有序了
for(int i=left;i<=right;i++){
nums[i] = tmp[i];
}
return;
}
//归并排序
void mergesort(vector<pair<int,int>>& nums,vector<pair<int,int>>& tmp,int left,int right,vector<int>& res) {
if(left < right){
int mid = left+(right-left)/2;
mergesort(nums,tmp,left,mid,res);
mergesort(nums,tmp,mid+1,right,res);
//合并nums[left,mid] nums[mid+1,right]
merge(nums,tmp,left,mid,right,res);
}
return;
} };

315. Count of Smaller Numbers After Self(二分或者算法导论中的归并求逆序数对)的更多相关文章

  1. [LeetCode] 315. Count of Smaller Numbers After Self (Hard)

    315. Count of Smaller Numbers After Self class Solution { public: vector<int> countSmaller(vec ...

  2. leetcode 315. Count of Smaller Numbers After Self 两种思路(欢迎探讨更优解法)

    说来惭愧,已经四个月没有切 leetcode 上的题目了. 虽然工作中很少(几乎)没有用到什么高级算法,数据结构,但是我一直坚信 "任何语言都会过时,只有数据结构和算法才能永恒". ...

  3. leetcode 315. Count of Smaller Numbers After Self 两种思路

    说来惭愧,已经四个月没有切 leetcode 上的题目了. 虽然工作中很少(几乎)没有用到什么高级算法,数据结构,但是我一直坚信 "任何语言都会过时,只有数据结构和算法才能永恒". ...

  4. 315. 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 ...

  5. [LeetCode] 315. Count of Smaller Numbers After Self 计算后面较小数字的个数

    You are given an integer array nums and you have to return a new counts array. The countsarray has t ...

  6. LeetCode 315. Count of Smaller Numbers After Self

    原题链接在这里:https://leetcode.com/problems/count-of-smaller-numbers-after-self/ 题目: You are given an inte ...

  7. 315.Count of Smaller Numbers After Self My Submissions Question

    You are given an integer array nums and you have to return a new counts array. Thecounts array has t ...

  8. 315. Count of Smaller Numbers After Self(Fenwick Tree)

    You are given an integer array nums and you have to return a new counts array. The counts array has ...

  9. 第十四周 Leetcode 315. Count of Smaller Numbers After Self(HARD) 主席树

    Leetcode315 题意很简单,给定一个序列,求每一个数的右边有多少小于它的数. O(n^2)的算法是显而易见的. 用普通的线段树可以优化到O(nlogn) 我们可以直接套用主席树的模板. 主席树 ...

随机推荐

  1. Go 并发操作

    goroutine 在其他的编程语言中,线程调度是交由os来进行处理的. 但是在Go语言中,会对此做一层封装,Go语言中的并发由goroutine来实现,它类似于用户态的线程,更类似于其他语言中的协程 ...

  2. 晋城6397.7539(薇)xiaojie:晋城哪里有xiaomei

    晋城哪里有小姐服务大保健[微信:6397.7539倩儿小妹[晋城叫小姐服务√o服务微信:6397.7539倩儿小妹[晋城叫小姐服务][十微信:6397.7539倩儿小妹][晋城叫小姐包夜服务][十微信 ...

  3. MeteoInfoLab脚本示例:TOMS HDF数据

    TOMS (Total Ozone Mapping Spectrometer)数据是全球臭氧观测.脚本程序: #Add data file folder = 'D:/Temp/hdf/' fns = ...

  4. spring boot:thymeleaf模板中insert/include/replace三种引用fragment方式的区别(spring boot 2.3.3)

    一,thymeleaf模板中insert/include/replace三种引用fragment方式的区别 insert: 把整个fragment(包括fragment的节点tag)插入到当前节点内部 ...

  5. 一文读懂Redis常见对象类型的底层数据结构

    Redis是一个基于内存中的数据结构存储系统,可以用作数据库.缓存和消息中间件.Redis支持五种常见对象类型:字符串(String).哈希(Hash).列表(List).集合(Set)以及有序集合( ...

  6. HTML轮播(1)

    前言 要想实现轮播,我们就得先把最基础的功能实现,那就是滚动,实现了滚动后就可以继续扩展,完成更多想要的效果 CSS <style> #LB { width: 100%; height: ...

  7. 使用Navicat远程连接阿里云ECS服务器上的MySQL数据库

    一.必须给服务器的安全组规则设置端口放行规则,在管理控制台中设置: 之后填写配置,授权对象是授权的IP,其中0.0.0.0/0为所有IP授权,之后保存; 二.Navicat使用的配置 在编辑连接处,要 ...

  8. 全球首个优秀的华人.net微服务框架 作者:百大僧

    话不多说,直接上地址 https://gitee.com/shoubashou/NetCoreMicroService,目标斩获10000star, 通往牛逼的路上,风景差得让人只说脏话. 是全球首个 ...

  9. SLF4J :Failed to load class "org.slf4j.impl.StaticLoggerBinder".

    错误提示 SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to ...

  10. Qlik Sense学习笔记之Mashup开发(一)

    date: 2018-12-21 12:33:29 updated: 2018-12-21 12:33:29 Qlik Sense学习笔记之Mashup开发(一) 1.基于Qlik Sense API ...