标签:begin end Offer int nums 51 数组 逆序
剑指 Offer 51. 数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 \(1\):
输入: \([7,5,6,4]\)
输出: \(5\)
思路:
还是权值线段树+离散化,类似LC315的操作从右往左边扫描,先查询后插入,将查询的结果保存在res中
/**
* ALGORIHTM_OFFER512_CPP
* @author : MWT
* @date : 17:03 2022/5/18
*
*/
#include <algorithm>
#include <cstdio>
#include <vector>
#include <iostream>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
class Solution {
private:
static const int MAXN = 1e5;
struct Node {
int l, r, val;
} T[MAXN << 2];
void build(int root, int l, int r) {
T[root].l = l, T[root].r = r, T[root].val = 0;
if (l == r)return;
int mid=(l+r)>>1;
build(root << 1, l, mid);
build(root << 1 | 1, mid+1, r);
}
int pushup(int root) {
return T[root].val = T[root << 1].val + T[root << 1 | 1].val;
}
void update(int root, int q, int x) {
if (T[root].l == T[root].r) {
T[root].val += x;
return;
}
int mid = (T[root].l + T[root].r) >> 1;
if (q <= mid)update(root << 1, q, x);
else update(root << 1 | 1, q, x);
pushup(root);
}
int query(int root, int l, int r) {
int ans = 0;
if (T[root].l >= l && T[root].r <= r)return T[root].val;
int mid = (T[root].l + T[root].r) >> 1;
if (l <= mid)ans += query(root << 1, l, r);
if (r > mid)ans += query(root << 1 | 1, l, r);
return ans;
}
int dequery(int root, int len) {
if (T[root].l == T[root].r)return T[root].l;
if (T[root << 1].val >= len)return dequery(root << 1, len);
else return dequery(root << 1 | 1, len - T[root << 1].val);
}
vector<int> a;//复制原数组内容
int getid(int x){
return lower_bound(a.begin(), a.end(), x) - a.begin() + 1;
}
public:
int reversePairs(vector<int> &nums) {
int sz = (int)nums.size();
a.assign(nums.begin(), nums.end());
sort(a.begin(), a.end());
a.erase(unique(a.begin(), a.end()), a.end());
build(1,1,1e5);
int res=0;
for(int i=sz-1;i>=0;--i){
int id=getid(nums[i]);
res+=query(1,1,id-1);
update(1,id,1);
}
return res;
}
};
标签:begin,end,Offer,int,nums,51,数组,逆序 来源: https://www.cnblogs.com/ftwftw/p/_0518.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。