【ACWing】113. 特殊排序

本文介绍了一种在N个元素间通过最多10000次询问获取大小关系并进行特殊排序的方法,利用归并排序算法,其时间复杂度为O(NlogN),空间复杂度为O(N)。
摘要由CSDN通过智能技术生成

题目地址:

https://www.acwing.com/problem/content/description/115/

N N N个元素,编号 1 , 2.. N 1,2..N 1,2..N,每一对元素之间的大小关系是确定的,关系具有反对称性,但不具有传递性。注意:不存在两个元素大小相等的情况。也就是说,元素的大小关系是 N N N个点与 N × ( N − 1 ) 2 \frac{N×(N−1)}{2} 2N×(N1)条有向边构成的任意有向图。然而,这是一道交互式试题,这些关系不能一次性得知,你必须通过不超过 10000 10000 10000次提问来获取信息,每次提问只能了解某两个元素之间的关系。现在请你把这 N N N个元素排成一行,使得每个元素都小于右边与它相邻的元素。你可以通过我们预设的bool函数compare来获得两个元素之间的大小关系。例如,编号为 a a a b b b的两个元素,如果元素 a a a小于元素 b b b,则compare(a,b)返回true,否则返回false。将 N N N个元素排好序后,把他们的编号以数组的形式输出,如果答案不唯一,则输出任意一个均可。

数据范围:
1 ≤ N ≤ 1000 1≤N≤1000 1N1000

可以直接归并排序。归并排序的比较次数是小于 N log ⁡ 2 N N\log_2N Nlog2N的。代码如下:

// Forward declaration of compare API.
// bool compare(int a, int b);
// return bool means whether a is less than b.
#include <vector>
using namespace std;

class Solution {
 public:
  vector<int> specialSort(int N) {
    vector<int> v;
    for (int i = 1; i <= N; i++) v.push_back(i);
    merge_sort(v, 0, v.size() - 1);
    return v;
  }

  void merge_sort(vector<int>& v, int l, int r) {
    if (l >= r) return;
    static vector<int> tmp(v.size());
    int mid = l + r >> 1;
    merge_sort(v, l, mid);
    merge_sort(v, mid + 1, r);
    int i = l, j = mid + 1, idx = i;
    while (i <= mid && j <= r)
      if (compare(v[i], v[j]))
        tmp[idx++] = v[i++];
      else
        tmp[idx++] = v[j++];

    while (i <= mid) tmp[idx++] = v[i++];
    while (j <= r) tmp[idx++] = v[j++];
    for (int i = l; i <= r; i++) v[i] = tmp[i];
  }
};

时间复杂度 O ( N log ⁡ N ) O(N\log N) O(NlogN),空间 O ( N ) O(N) O(N)

  • 14
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值