树状数组求逆序数
来源:互联网 发布:pdf阅读器下载 知乎 编辑:程序博客网 时间:2024/05/20 04:50
树状数组的简介见:
http://blog.csdn.net/x_iya/article/details/8943264
什么是逆序数?
在一个排列中,如果一对数的前后顺序与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序数的总数就是这个排列的逆序数。
一般的解法:
当数据的范围较小时,比如maxn=100000,那么我们可以开一个数组C[maxn],来记录前面数据的出现情况,初始化为0。
当数据a出现时,就令C[a]=C[a]+1。这样的话,欲求某个数a的逆序数,只需要算出在当前状态下C[a+1]到C[maxn]中有多少个1,因为这些位置的数在a之前出现且比a大。但是若每添加一个数据a时,就得从a+1到maxn搜一遍,复杂度太高了。
树状数组却能很好的解决这个问题,同样开一个数组C[maxn],初始化为0,C[i]记录下i结点所管辖范围内当前状态有多少个数被添加;当添加数据a时,就向上更新C,这样一来,欲求a的逆序数时,只需要算getSum(maxn)-getSum(a);sum(a)表示a之前出现了多少个1,也即有多少小于等于a的元素个数。
或者用i记录添加数据的次序(记录添加了几个数据了),i-getSum(a)也即为a的逆序数。
public class Solution { private int[] arr; private int maxn = 100000; private int LowBit(int x) { return x & (-x); } private int getSum(int pos) { int sum = 0; while (pos > 0) { sum += arr[pos]; pos -= LowBit(pos); } return sum; } private void update(int pos, int val) { while (pos <= maxn) { arr[pos] += val; pos += LowBit(pos); } } public int resolve(int[] nums) { int count = 0; arr = new int[maxn]; for (int i = 0; i < nums.length; i++) { update(nums[i], 1); count += (i + 1 - getSum(nums[i])); } return count; } public static void main(String[] args) { Solution solution = new Solution(); int[] arr = {5, 3, 4, 2, 1}; System.out.println(solution.reversePairs(arr)); }}
阅读全文
0 0
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组 求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 树状数组 求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- 求逆序数(树状数组)
- 树状数组 求逆序数
- 树状数组 求逆序数
- 树状数组求逆序数
- 树状数组求逆序数
- Centos6.5安装docker
- 简谈JAVA基础--IO流
- nginx学习随笔--pid
- jsp简介和el标签 jstl标签
- python安装numpy、scripy失败总结
- 树状数组求逆序数
- 校招准备系列:每天一道算法题(9)-单例
- table border合并无间隙 列宽度固定不换行
- 精致傲娇的品牌 只卖呆萌的价格 对对全自动外卖打印机评测
- 设计模式转载
- Struts1的标签及意义
- java基础(个人学习笔记)A
- Android Studio教程从入门到精通
- C# 实现AOP 的几种常见方式