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 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(二分或者算法导论中的归并求逆序数对)的更多相关文章
- [LeetCode] 315. Count of Smaller Numbers After Self (Hard)
315. Count of Smaller Numbers After Self class Solution { public: vector<int> countSmaller(vec ...
- leetcode 315. Count of Smaller Numbers After Self 两种思路(欢迎探讨更优解法)
说来惭愧,已经四个月没有切 leetcode 上的题目了. 虽然工作中很少(几乎)没有用到什么高级算法,数据结构,但是我一直坚信 "任何语言都会过时,只有数据结构和算法才能永恒". ...
- leetcode 315. Count of Smaller Numbers After Self 两种思路
说来惭愧,已经四个月没有切 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 counts array has ...
- [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 ...
- LeetCode 315. Count of Smaller Numbers After Self
原题链接在这里:https://leetcode.com/problems/count-of-smaller-numbers-after-self/ 题目: You are given an inte ...
- 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 ...
- 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 ...
- 第十四周 Leetcode 315. Count of Smaller Numbers After Self(HARD) 主席树
Leetcode315 题意很简单,给定一个序列,求每一个数的右边有多少小于它的数. O(n^2)的算法是显而易见的. 用普通的线段树可以优化到O(nlogn) 我们可以直接套用主席树的模板. 主席树 ...
随机推荐
- 用ip xfrm搭ipsec隧道
拓扑如下 基本的IP配置就不说了,直接写重点,在LS上配置 #配置SA ip xfrm state add src 194.168.10.4 dst 194.168.10.5 proto esp sp ...
- ansible2.4安装和体验
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- go sync.WaitGroup
package mainimport ( "fmt" "sync")func say(i int ,wg *sync.WaitGroup) { defer wg ...
- centos8平台使用parted管理分区
一,parted的用途 parted是GNU发布的强大的分区工具, parted命令可以划分单个分区大于2T的GPT格式的分区,也可以划分普通的MBR分区. 因为fdisk命令对于大于2T的分区无法划 ...
- Nexus 安装教程
Nexus 安装教程 一. CentOS设置 1. 更换阿里源 curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/ ...
- Python之for循环和列表
for循环: 有限循环 基本语法: for 变量 in 可迭代对象: 循环体 也可使用break,continue,for else list列表初识: 列表可放任意数据类型:[int,str,boo ...
- python 操作conf配置文件方法
参考文章链接:https://blog.csdn.net/qq_23587541/article/details/85019610
- 推荐4款个人珍藏的IDEA插件!帮你写出不那么差的代码
@ 目录 Codota:代码智能提示 代码智能补全 代码智能搜索 Alibaba Java Code Guidelines:阿里巴巴 Java 代码规范 手动配置检测规则 使用效果 CheckStyl ...
- docker启动redis并设置密码
docker启动redis并设置密码: docker run -d --name redis -p 6379:6379 redis --requirepass "password" ...
- 报错 source-1.6 中不支持 diamond运算符
报错 source-1.6 中不支持 diamond运算符 解决方式 在pom.xml文件中修改 <plugin> <groupId>org.apache.maven.plug ...