zoukankan      html  css  js  c++  java
  • 算法进阶指南—特殊排序

    题意:有N个数,每两个数之间的大小关系要通过询问来得知,但是每个数之间的大小关系不具有传递性,比如 a<b  ,  b< c不一定有a<c。

    现在问你能否在10000次询问内把这N个数排成一列,使得相邻两个数,左边比右边小。

    思路:把前  i - 1个数字排好序后,第  i  个数字应该插入到什么位置,则二分前面  i - 1 的有序序列,利用中间值mid 来判定i的插入位置。

    判定方法,若mid< i 则mid 右半边是合法的,另 l = mid,若mid >i,则 mid 左半边是合法的,另 r= mid-1;

    找到插入位置r后把  i  插入到最后一个位置,把 i 从最后一个位置一直换到第r+1个位置,然后再判断它与 r的关系若小于r,把 r 与r+1位置上的数对换。

    前i-1个排序运用了插入排序,每插入一个新的数都用二分的方法取判定它的位置。最后由于每次二分判定位置次数最多为n*log n.所以两个数比较大小的询问也最多提出n*log n次。

    加起来总共为 2*log n+3*log n+........+n*log n 其小于10000次

    下面上代码:

    class Solution {
    public:
        vector<int> specialSort(int N) {
            vector<int> res;
            res.push_back(1);
            for(int i=2;i<=N;i++)
            {
                int l=0,r=res.size()-1;
                while(l<r)
                {
                int    mid=(l+r+1)>>1;
                    if(compare(res[mid],i))
                    l=mid;
                    else
                    r=mid-1;
                 }
                 
                 res.push_back(i);
                 for(int j=res.size()-2;j>r;j--)
                 swap(res[j],res[j+1]);
                 if(!compare(res[r],res[r+1]))
                 swap(res[r],res[r+1]);      
             } 
            return res;      
            
        }
    };
  • 相关阅读:
    JAVA中的除法运算
    虚拟内存的设置和相关问题的解决方法
    div + css + js 打造HTML的tab控件
    body居中 兼容ie和ff
    js 获取当前页面源代码
    windows系统的全部命令
    HR线条样式CSS定制
    PHP5.3.5以及Apache2.2.17安装简介
    如何使用apache在本地服务器虚拟域名来测试网站
    CakePHP常用技巧总结
  • 原文地址:https://www.cnblogs.com/rainyskywx/p/10349571.html
Copyright © 2011-2022 走看看