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. 多测师_高级讲师肖sir讲解html中 Button跳转连接方法归纳

    第一种方法: 1.1<a href="http://www.baidu.com">   <input type="button" name=& ...

  2. day06 Pyhton学习

    一.昨日内容回顾 字典: 由{}表示,内部存储key:value 要求: key不能重复 key必须可哈希.不可变 value没有限制 没有索引和切片 增删改查 新增: dic.[新key]=valu ...

  3. 置Hugo的代码高亮

    +++ date="2020-10-17" title="设置Hugo的代码高亮" tags=["hugo"] categories=[&q ...

  4. linux(centos8):firewalld使用ipset管理ip地址的集合

    一,firewalld中ipset的用途: 1,用途 ipset是ip地址的集合, firewalld使用ipset可以在一条规则中处理多个ip地址, 执行效果更高 ​对ip地址集合的管理也更方便 2 ...

  5. linux(centos8):用sort对文本内容排序

    一,sort的用途 1,作用: sort命令用于将文本文件内容加以排序. 它能够以行为单位来排序 2,sort常与uniq搭配使用,原因: 用uniq命令去重时, 需要相同的每行位置相邻才能生效, 所 ...

  6. Python中while循环初识

    基本结构 ​ while 条件: ​ 循环体 基本原理: ​ 1.先判断条件是否为True ​ 2.如果是True进入循环体 ​ 3.执行到循环体的底部 ​ 4.继续判断条件,条件为True,再次进入 ...

  7. Anderson《空气动力学基础》5th读书笔记 第4记——黏性流动入门

    目录 一.边界层的概念 二.边界层的产生原因 三.剪切力的公式 四.温度分布情况 五.雷诺数与层流.湍流 一.边界层的概念 我们先来介绍边界层的概念(边界层正是黏性流动的产物),边界层是紧挨物体的薄层 ...

  8. 模块二:ES新特性与TypeScript、JS性能优化

    一.请说出下列最终得执行结果,并解释为什么.

  9. 【洛谷】 cpp-->c 一道好玩的显示题

    P1538 这题真的好玩 题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同 ...

  10. c# vs2019 Window服务搭建

    一.创建一个Windows Service         我的IDE开发工具使用的是vs2019,和之前的vs版本不大相同,所有添加了详细的截图说明.         首先,选择新建项目,项目类型选 ...