zoukankan      html  css  js  c++  java
  • 对排序次数问题的思考——面试

    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次,实际是两次,暂时没有想到好的方法,不知博友有什么好的想法?

  • 相关阅读:
    linux下查找文件及查找包含指定内容的文件常用命令
    小程序与h5之前切换频繁时候,点击无反应
    vue项目微信分享之后路由链接被破坏问题
    async-await用法
    小程序input组件获得焦点时placeholder内容有重影
    es6语法在ios低版本的支持性
    h5页面避免两个页面反复跳转死循环
    小程序getLocation出现的各种问题汇总
    小程序组件跳转页面存在兼容问题
    nigix反向代理
  • 原文地址:https://www.cnblogs.com/huhuuu/p/3442151.html
Copyright © 2011-2022 走看看