算法进阶指南—特殊排序
Posted rainyskywx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法进阶指南—特殊排序相关的知识,希望对你有一定的参考价值。
题意:有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; } };
以上是关于算法进阶指南—特殊排序的主要内容,如果未能解决你的问题,请参考以下文章