归并排序求逆序对的数量

这篇具有很好参考价值的文章主要介绍了归并排序求逆序对的数量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、题目来源

AcWing算法基础课-788.逆序对的数量

二、题目描述

给定一个长度为 \(n\) 的整数数列,请你计算数列中的逆序对的数量。

逆序对的定义如下:对于数列的第 \(i\) 个和第 \(j\) 个元素,如果满足 \(i < j\)\(a[i] > a[j]\),则其为一个逆序对;否则不是。

输入格式**

第一行包含整数 \(n\),表示数列的长度。

第二行包含 \(n\) 个整数,表示整个数列。

输出格式

输出一个整数,表示逆序对的个数。

数据范围

\(1 ≤ n ≤ 100000,\)
数列中的元素的取值范围 \([1, 10^9]\)

输入样例:

6
2 3 4 5 6 1 

输出样例:

5 

三、算法思路

本题基于归并排序的过程。

思路如下:

  1. 先将区间分为两段

  2. 满足逆序对条件的两个点有如下三种情况:

    1. 两个点都在左区间
    2. 两个点都在右区间
    3. 一个点在左边区间,一个点在右边区间
  3. 不断的递归排序的过程中,上述 \(1、2\) 情况都会转化为 \(3\) 的情况,所以答案直接加上左区间排序和右区间排序即可

  4. 由于归并之后两个区间都是有序的,所以如果当前左区间的数大于当前右区间的数,则左区间剩下的所有数都大于当前右区间的数,即满足逆序对的条件,res += mid - i + 1;文章来源地址https://www.toymoban.com/news/detail-711627.html

  • 如果直接暴力解题,从后往前遍历,时间复杂度\(O(n^2)\),采用归并排序解题时间复杂度为\(O(nlogn)\)
  • 注意思考上述三种情况,在不断划分区间的过程中,最后都会转化为第三种情况。
  • 数据量很大可能会爆int,所以用long long来存答案。

四、源代码

#include <iostream>

using namespace std;

const int N = 100010;

typedef long long LL;

int n;
int a[N];
int tmp[N];

LL merge_sort(int a[], int l, int r)
{
    if (l >= r) return 0;
    
    int mid = (l + r) >> 1;
    LL res = merge_sort(a, l, mid) + merge_sort(a, mid + 1, r);
    
    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (a[i] <= a[j])   tmp[k ++ ] = a[i ++ ];
        else    res += mid - i + 1, tmp[k ++ ] = a[j ++ ];
    while (i <= mid)    tmp[k ++ ] = a[i ++ ];
    while (j <= r)  tmp[k ++ ] = a[j ++ ];
    
    for (int i = l, j = 0; i <= r; ++i, ++j)    a[i] = tmp[j];
    
    return res;
}

int main()
{
    cin >> n;
    
    for (int i = 0; i < n; ++i) cin >> a[i];
    
    cout << merge_sort(a, 0, n - 1) << endl;
    
    return 0;
}

到了这里,关于归并排序求逆序对的数量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Codeforces Round 918 (Div. 4)F题归并逆序对

    Problem - F - Codeforces ———— 可以先练道逆序对的题:P1908 逆序对 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)  原理概括:(abcd当做一组降序的4个数,现在进行归并) ———— 然后注意这道F题, 两人之间只会打一次招呼 我们按左节点顺序排,这样前面的左边界都包含后面

    2024年01月23日
    浏览(9)
  • C++算法之动态规划(ACWING题目)

    动态规划时间复杂度:状态数量*转移计算量 线性DP 一.数字三角形 动态规划:     1.状态表示:         集合:f[i, j]表示所有从起点走到(i, j)的路径         属性:所有路径上的数字之和的最大值     2.状态计算:         如何得到f[i, j]?             从左边路径走到和

    2024年02月20日
    浏览(9)
  • C++ vector逆序排序的三种方法

    突然忘了快速逆序的方法,在网上搜索vector逆序发现没有,于是自己写一下,帮助大家快速查找。 假如你有一个vector里面有元素1,2,3,4,5,则逆序方法如下。 方法一: 方法一比方法二方便。 方法二: 方法三: 方法四(推荐): 你也可以通过使用rbegin,rend指针逆序排序

    2024年02月17日
    浏览(9)
  • 哈希表题目:原子的数量

    标题:原子的数量 出处:726. 原子的数量 8 级 要求 给你一个表示化学式的字符串 formula texttt{formula} formula ,返回每种原子的数量。 原子总是以一个大写字母开始,跟随零个或任意个小写字母,表示原子的名字。 如果数量大于 1 texttt{1} 1 ,原子后会跟着数字表示原子的数量

    2024年02月06日
    浏览(11)
  • 1239. 串联字符串的最大长度;2826. 将三个组排序;2563. 统计公平数对的数目

    1239. 串联字符串的最大长度;2826. 将三个组排序;2563. 统计公平数对的数目

    1239. 串联字符串的最大长度 核心思想:递归,选或者不选,定义dfs(i,pre)表示从i-n的满足要求的arr中选择字符串串联所能获得的最大长度为dfs(i,pre),pre表示已经选过的字符串所组成的集合。然后就有两种情况选,或者不选,选的话需要保证mask[i]和pre没有公共字母,dfs(i+1,p

    2024年02月11日
    浏览(10)
  • 【数据结构与算法】归并排序详解:归并排序算法,归并排序非递归实现

    【数据结构与算法】归并排序详解:归并排序算法,归并排序非递归实现

    归并排序是一种经典的排序算法,它使用了分治法的思想。下面是归并排序的算法思想: 递归地将数组划分成较小的子数组,直到每个子数组的长度为1或者0。 将相邻的子数组合并,形成更大的已排序的数组,直到最终得到一个完全排序的数组。 归并排序的过程可以分为三

    2024年01月22日
    浏览(15)
  • 考研算法31天:归并排序 【归并排序,分治】

    考研算法31天:归并排序 【归并排序,分治】

    算法介绍 归并算法其过程分为三步: 1.分:递归到最下面 2.治:两个元素之间排序。 3。归:递归到最下层然后返回,从两个元素变成四个元素再排序。 如下图所示: 动态图如下: 算法题目 算法ac代码:

    2024年02月11日
    浏览(9)
  • (排序) 剑指 Offer 51. 数组中的逆序对 ——【Leetcode每日一题】

    (排序) 剑指 Offer 51. 数组中的逆序对 ——【Leetcode每日一题】

    难度:困难 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。 示例 1: 输入: [7,5,6,4] 输出: 5 限制 : 0 = 数组长度 = 50000 💡思路:归并排序 预备知识 「 归并排序 」是用 分治 思想,分

    2024年02月11日
    浏览(18)
  • 题目:2511.最多可以摧毁的敌人城堡数量

    ​ 题目来源:         leetcode题目,网址:2511. 最多可以摧毁的敌人城堡数目 - 力扣(LeetCode) 解题思路:        顺序遍历数组,记录上一个我军城堡和没有城堡的位置。当碰到空位置时,若上一次更新的值为我军城堡,记录较大的摧毁数;当碰到我军城堡时,若上一次更

    2024年02月13日
    浏览(11)
  • 【初阶算法4】——归并排序的详解,及其归并排序的扩展

    【初阶算法4】——归并排序的详解,及其归并排序的扩展

    目录 前言 学习目标: 学习内容: 一、介绍归并排序 1.1 归并排序的思路 1.2 归并排序的代码 1.2.1 mergesort函数部分  1.2.2 process函数部分  1.2.3 merge函数部分  二、AC两道经典的OJ题目 题目一:逆序对问题 题目二:小和问题  三、练习一道LeetCode的题目 四、总结在什么情况下使

    2024年02月08日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包