美文网首页
最少的交换...找逆序对题解

最少的交换...找逆序对题解

作者: 步行植物 | 来源:发表于2019-06-10 19:46 被阅读0次

这个找逆序对的题真的搞了我很久,明明题目理解起来一点都不复杂嘤嘤嘤.最开始直接用冒泡,哈哈哈哈太天真了,后来改用插入排序,明明是和冒泡同样的复杂度......都是o(N^2),最后终于用了归并,复杂度是nlogn
原理早就弄懂了,但小细节没有处理好,一直是输出错误50%,我的天哪,终于做出来了,和其他博主的长篇大论比起来,这差不多是最简洁的代码了.先上题:

问题 D: 最少的交换

时间限制: 1 Sec 内存限制: 32 MB

题目描述

现在给你一个由n个互不相同的整数组成的序列,现在要求你任意交换相邻的两个数字,使序列成为升序序列,请问最少的交换次数是多少?

输入

输入包含多组测试数据。每组输入第一行是一个正整数n(n<500000),表示序列的长度,当n=0时。
接下来的n行,每行一个整数a[i](0<=a[i]<=999999999),表示序列中第i个元素。

输出

对于每组输入,输出使得所给序列升序的最少交换次数。

样例输入

9
1
0
5
4
3
1
2
3
0

样例输出

6
0

#include<cstdio>
#include<iostream>
using namespace std;
void msort(int begin, int end, long long &ans, int* a, int* c )//归并排序
{
    if (begin == end)    //左边和右边相等就return
        return;
    int mid = (begin + end) / 2;
        int i = begin;    //用来记录左半边数组的下标
        int j = mid + 1;    //用来记录右半边数组的下标
        int k = begin;    //用来指向临时放入那个数组
    msort(begin, mid,ans,a,c), msort(mid + 1, end,ans,a,c);
    while (i <= mid && j <= end)    //右半边和左半边都还没有遍历完
        if (a[i] <= a[j])
            c[k++] = a[i++];
        else
            c[k++] = a[j++], ans += mid - i + 1;   
/*统计答案,右边数组中还没有放进去的都是逆序*/
    while (i <= mid)    //把最后剩下的加上
        c[k++] = a[i++];
    while (j <= end)
        c[k++] = a[j++];
    for (int l = begin; l <= end; l++)   //再放回a
        a[l] = c[l];
}

int main()
{
    int n;
    while (1)
    {
        cin >> n;
        if (n == 0)
            break;
        int* a = new int[n];    //输入放在a里
        int* c = new int[n];    //c是用来辅助排序的
/*最开始开辟临时数组会比在函数里临时开辟节省开销,具体见MOOC浙大数据结构归并排序,姥姥有讲过*/
        for (int i = 1; i <= n; i++)
            cin >> a[i];
/*在最前面全局定义a[n]和c[n]还有ans很容易出问题,所以最好还是每次重新开辟数组比较保险.*/
        long long ans = 0;
        msort(1, n,ans,a,c);
        cout << ans << endl;
    }
    return 0;
}

归并排序用到了二分的思想,在排序过程中如果a[i]<=a[j]就不会产生逆序对,如果a[i]>a[j]就会产生mid−i+1个逆序对,因为做归排的时候l~mid和mid+1~r都是已经排好序的所以如果a[i]>a[j]那么a[i+1]~a[mid]也就都大于a[j]

洛谷上也有题解:
https://www.luogu.org/problemnew/solution/P1908
姥姥的归并课程:
https://www.icourse163.org/learn/ZJU-93001?tid=1003997005#/learn/content?type=detail&id=1007588513

一定要牢记各种排序的时间复杂度,就不会出现用插入换冒泡结果复杂度相同的尴尬场景了

//错误:时间超限百分之50,用简单选择排序

#include <iostream>
#include<vector>
using namespace std;

void judge(int n)
{
    vector<int>array;
    for (int i = 0; i < n; i++)
    {
        int b;
        cin >> b;       //每个数字
        array.push_back(b);
    }
    int total = 0;
    for (int i = 0; i < n; i++)     //选择排序执行n次
    {
        int max = -1, keep = 0;    
        int j = 0;
        for (; j < n - i; j++)      //每次从从后往前推一个字
            if (max < array[j])
            {
                max = array[j];
                keep = j;
            }
        if (j != n - i - 1)     //如果最大的不是最后一个就交换
        {
            total += n - i - keep - 1;      //从keep移动到n-i-1这个位置(下标),移动了这些步
            array.erase(array.begin() + keep);
            if (i == 0)
                array.push_back(max);
            if (i != 0)
                array.insert(array.begin() + n - i - keep,1, max);
        }
    }
    cout << total << endl;
}


int main()
{
    int n;      //
    while (1)
    {
        cin >> n;
        if (n == 0)
            break;
        judge(n);
    }
    return 0;
}

相关文章

  • 最少的交换...找逆序对题解

    这个找逆序对的题真的搞了我很久,明明题目理解起来一点都不复杂嘤嘤嘤.最开始直接用冒泡,哈哈哈哈太天真了,后来改用插...

  • ACM归并排序求逆序对-火柴排队

    http://codevs.cn/problem/3286/这里引用ssoj官网题解:贪心+逆序对。分析如下:对距...

  • 数组逆序

    数组逆序: 数组中的元素进行,位置上的交换 逆序实现思想:数组最远端位置交换 数组的指针思想:就是数组的索引 大指...

  • 51NOD 1019 逆序数

    逆序数 分析 逆序数的意义:就是选择排序中对元素交换的次数。 普通的比较时间复杂度都是O(N^2),肯定是不能通过...

  • 排序算法之——交换类排序

    交换类排序的基本思想 对待排序列记录的关键字两两进行比较,只要发现两个记录为逆序就进行交换,直到没有逆序的记录为止...

  • 逆序对

    在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。给你一个数组,求出这个数组中逆序对的...

  • 逆序对

    逆序对的定义 假定有一个序列,对于序列中任意两个元素和,如果有,则称和是一对逆序对。我们接下来以洛谷P1908 逆...

  • Python编程练习035:逆序列表和类的方法变量

    实例: 逆序列表 题目 将一个数组逆序输出。 程序分析 依次交换位置,或者直接调用reverse方法。 方法一: ...

  • 七大排序之冒泡排序

    基本思想:在[lo,hi]区间内,从左往右,依次对相邻元素进行比较,若逆序,交换两元素位置(稳定排序),直至各元素...

  • 详解冒泡排序算法

    基本思想 冒泡排序的基本思想是:通过对待排序的序列从前向后依次比较相邻元素的值,如果发现逆序则交换。逆序的含义:如...

网友评论

      本文标题:最少的交换...找逆序对题解

      本文链接:https://www.haomeiwen.com/subject/rjstfctx.html