剑指 Offer 51. 数组中的逆序对 + 归并排序 + 树状数组
剑指 Offer 51. 数组中的逆序对
Offer_51
题目描述

方法一:暴力法(双层循环,超时)
package com.walegarrett.offer;
/**
* @Author WaleGarrett
* @Date 2021/2/9 9:12
*/
/**
* 题目详情:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
* 输入一个数组,求出这个数组中的逆序对的总数。
*/
import java.util.Arrays;
/**
* 方法一:暴力解法(超时TLE)
*/
public class Offer_51 {
public int reversePairs(int[] nums) {
int len = nums.length;
int cnt = 0;
for(int i=0; i<len; i++){
int now = nums[i];
for(int j=0;j<i;j++){
if(nums[j] > now)
cnt++;
}
}
return cnt;
}
}
方法二:归并排序法

/**
* 方法二:归并排序
*/
class Offer_51_2 {
public int reversePairs(int[] nums) {
int len = nums.length;
if(len < 2)
return 0;
int[] second = Arrays.copyOf(nums, len);
return reversePairs(nums, 0, len-1, new int[len]);
}
int reversePairs(int[] nums, int left, int right, int[] tmp){
if(left == right)
return 0;
int mid = (left + right) >> 1;
int leftCnt = reversePairs(nums, left, mid, tmp);
int rightCnt = reversePairs(nums, mid+1, right, tmp);
//左半部分的最大值小于右半部分的最小值,所以这两部分的和没有逆序数对
if(nums[mid] <= nums[mid+1])
return leftCnt + rightCnt;
int crossCnt = mergeAndCount(nums, left, right, tmp);
return leftCnt + rightCnt + crossCnt;
}
//合并并统计逆序数
int mergeAndCount(int[] nums, int left, int right, int[] tmp){
for(int i=left;i<=right;i++){
tmp[i] = nums[i];
}
int mid = (left + right) >> 1;
int cnt = 0;
int i = left;
int j = mid+1;
for(int k=left; k<=right; k++){
if(i == mid+1){
nums[k] = tmp[j];
j++;
}else if(j == right+1){
nums[k] = tmp[i];
i++;
}else if(tmp[i] <= tmp[j]){//左指针右移
nums[k] = tmp[i];
i++;
}else{//右指针右移
nums[k] = tmp[j];
j++;
cnt += (mid-i+1);
}
}
return cnt;
}
}

方法三:树状数组

/**
* 方法三:树状数组
*/
//树状数组
class BIT{
int[] tree;
int n;
public BIT(int n){
this.n = n;
this.tree = new int[n+1];
}
public static int lowbit(int x){
return x&(-x);
}
public void update(int i){
while(i<=n){
++ tree[i];
i += lowbit(i);
}
}
public int query(int i){
int cnt = 0;
while(i!=0){
cnt += tree[i];
i -= lowbit(i);
}
return cnt;
}
}
class Offer_51_3 {
public int reversePairs(int[] nums) {
int len = nums.length;
int[] tmp = new int[len];
tmp = Arrays.copyOf(nums, len);
//离散化:获取元素之间的相对排名
Arrays.sort(tmp);
for(int i=0; i<len; i++){
nums[i] = Arrays.binarySearch(tmp, nums[i]) + 1;
}
BIT bit = new BIT(len);
int ans = 0;
for(int i = len-1; i>=0; i--){
ans+=bit.query(nums[i] - 1);
bit.update(nums[i]);
}
return ans;
}
}

参考题解:数组中的逆序对
剑指 Offer 51. 数组中的逆序对 + 归并排序 + 树状数组的更多相关文章
- [剑指offer]51-数组中的逆序对(归并排序)
题目链接 https://www.nowcoder.com/questionTerminal/96bd6684e04a44eb80e6a68efc0ec6c5 题意 在数组中的两个数字,如果前面一个数 ...
- AcWing 107. 超快速排序(归并排序 + 逆序对 or 树状数组)
在这个问题中,您必须分析特定的排序算法----超快速排序. 该算法通过交换两个相邻的序列元素来处理n个不同整数的序列,直到序列按升序排序. 对于输入序列9 1 0 5 4,超快速排序生成输出0 1 4 ...
- 力扣Leetcode 面试题51. 数组中的逆序对 - 归并排序
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5 限制: 0 <= ...
- 九度OJ 1348 数组中的逆序对 -- 归并排序
题目地址:http://ac.jobdu.com/problem.php?pid=1348 题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求 ...
- 51nod1019逆序数(归并排序/树状数组)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1019 题意:中文题诶- 思路: 方法1:归并排序- 归并排序过 ...
- 【BZOJ 3295】动态逆序对 - 分块+树状数组
题目描述 给定一个1~n的序列,然后m次删除元素,每次删除之前询问逆序对的个数. 分析:分块+树状数组 (PS:本题的CDQ分治解法见下一篇) 首先将序列分成T块,每一块开一个树状数组,并且先把最初的 ...
- Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2886 Solved: 924[Submit][Stat ...
- Day2:T4求逆序对(树状数组+归并排序)
T4: 求逆序对 A[I]为前缀和 推导 (A[J]-A[I])/(J-I)>=M A[j]-A[I]>=M(J-I) A[J]-M*J>=A[I]-M*I 设B[]=A[]-M*( ...
- bzoj3295 [Cqoi2011]动态逆序对 cdq+树状数组
[bzoj3295][Cqoi2011]动态逆序对 2014年6月17日4,7954 Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数. ...
随机推荐
- Python3.9.1中如何使用match方法?
接触编程的朋友都听过正则表达式,在python中叫re模块,属于文字处理服务里面的一个模块.re里面有一个方法叫match,接下来的文章我来详细讲解一下match. 作为新手,我建议多使用帮助文档,也 ...
- 向 3D 世界迈出一小步
前言 OpenGL 的学习资料很多,一个是比较著名的 OpenGL 红宝书<OpenGL 编程指南>,可以在这里 http://opengl-redbook.com/ 下载该书配套的源代码 ...
- MySQL 主从复制(上)
目录 主从复制前提 主从复制原理 涉及的文件 & 线程 Master 主库 Slave 从库 主从复制的搭建 主库配置 配置 /etc/my.cnf 建立专用复制用户 查看 Binlog 信息 ...
- Linux-字符处理命令
目录 1.sort(排序) 2.uniq(不相邻的两行重复不会去除) 3.cut(取列,截取字段) 4.wc(统计行.单词.字符数) 1.sort(排序) 选项: -t # 指定分隔符 -k # 指定 ...
- Django的settings配置文件
一.邮件配置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.qq.com' EMAI ...
- SPOJ VLATTICE Visible Lattice Points(莫比乌斯反演)题解
题意: 有一个\(n*n*n\)的三维直角坐标空间,问从\((0,0,0)\)看能看到几个点. 思路: 按题意研究一下就会发现题目所求为. \[(\sum_{i=1}^n\sum_{j=1}^n\su ...
- Spring(三) Spring IOC 初体验
Web IOC 容器初体验 我们还是从大家最熟悉的 DispatcherServlet 开始,我们最先想到的还是 DispatcherServlet 的 init() 方法.我们发现在 Dispath ...
- Google PageSpeed Insights : 网站性能优化检测工具
1 1 https://developers.google.com/speed/pagespeed/insights/ PageSpeed Insights 使您的网页在所有设备上都能快速加载. 分析 ...
- 2018 free pdf ebooks
2018 free pdf ebooks https://gist.github.com/xgqfrms-GitHub/f606efb0d4bce884c873518647e79f2f https:/ ...
- background & background-image & border-image
background & background-image & border-image https://developer.mozilla.org/en-US/docs/Web/CS ...