对排序次数问题的思考——面试

1.有一组无序的数,只能两两相邻交换,最少交换几次可以使数组有序

 由两两相邻交换考虑到逆序数,这个问题就转化到了逆序数一共有几对。

 对于逆序数对数的计算,普通的有O(n*n)的算法,当然可以通过树状数组优化N*log(N)

2.有一组无序的数(数字两两不相等:如3 1 1 1就不行),可以任意相互交换,最少交换几次可以使数组有序

 问题其实可以转化到选择排序,比如 6 2 1 3 4,第一次将最小的取出放到第一位,如果最小的本来就在第一位,步数就不变,反之加1后交换位置 1 2 6 3 4,后面依次进行

 O(n*n)的方法

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;

int s[100999];
int s2[100999];

int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        int i,j;
        for(i=1;i<=n;i++){
            scanf("%d",&s[i]);
            s2[i]=s[i];
        }
        sort(&s2[1],&s2[n+1]);

        int add=0;
        for(i=1;i<=n;i++){
            if(s2[i]==s[i])continue;
            for(j=i+1;j<=n;j++){
                if(s2[i]==s[j]){
                    add++;
                    swap(s[i],s[j]);
                    break;
                }
            }
        }
        
        printf("%d
",add);
    }

    return 0;
}
View Code

 还可以继续优化到N*log(N)

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;

int s[100999];

struct data{
    int no;
    int newno;
    int v;
}node[100999];

int cmp(data x,data y){
    return x.v<y.v;
}

int cmp2(data x,data y){
    return x.no<y.no;
}

int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        int i,j;
        for(i=1;i<=n;i++){
            scanf("%d",&s[i]);
            node[i].no=i;
            node[i].v=s[i];
        }
        sort(&node[1],&node[1+n],cmp);
        for(i=1;i<=n;i++){
            node[i].newno=i;
            s[i]=node[i].no;
        }
        sort(&node[1],&node[1+n],cmp2);//离散化
    
        int add=0;
        for(i=1;i<=n;i++){
            if(node[i].newno==i)continue;
            add++;
            int no=s[i];
            s[node[i].newno]=no;
            swap(node[i].newno,node[no].newno);
        }

        printf("%d
",add);
    }

    return 0;
}
View Code

3.有一组无序的数(数字两两可以相等:如3 1 1 1),可以任意相互交换,最少交换几次可以使数组有序

 先预处理,快排原数组 1 1 1 3,将排序后数组中与原数组同位置数字不相同的生成新数组3 1再按第二题的方法处理

 发现这样有问题!考虑3 2 1 1,按我的方法是3次,实际是两次,暂时没有想到好的方法,不知博友有什么好的想法?

原文地址:https://www.cnblogs.com/huhuuu/p/3442151.html