修改排序的数组或每次对数组进行排序

Modify sorted array or sort the array everytime?

本文关键字:数组 排序 修改      更新时间:2023-10-16

问题:给定尺寸n的数组,打印带有连续元素的大小k的子集。

N = 10, K = 4 
8 4 7 5 1 10 3 9 2 6
Output:
4 5 7 8, 1 4 5 7, 1 5 7 10, 1 3 5 10, ...

方法1:对所有子集和打印进行分类。

复杂性分析:

复制k元素:o((n -k 1( *(k((//sub集 * sub集的大小

排序子集:使用stl,排序子集的最坏情况是o(k log k(。

因此,o((n -k 1( *(k( (n -k 1( *(k log k((

方法2:从输出序列中,连续的子集合不同的元素不同。因此,对于第二个子集,删除第一个元素并在正确位置插入K 1元素。

复杂性分析:

创建第一个子集:k

删除并插入 - 线性搜索(应该优化!(:k

因此,o(k (n -k 1( *(k((

我想知道第二种方法是否更快?有很大的收益吗?值得不使用STL实现吗?可以进一步改善吗?还有其他方法吗?以及有关STL容器实施的任何建议。

是否允许重复?

如果不允许重复,请使用std::set,否则请使用std::multisetsetmultiset将一直整理您的元素,并且每个插入都将进入正确的有序位置。您不必担心什么时候对它们进行分类。

在插入过程中进行所有分类的所有内容都是更便宜的,因为当您必须搜索时,您不必与所有元素进行比较,而只需比较它们的一个子集。

使用std::multiset。这将是简单干净的:

vector<int> v = input();
multiset<int> s;
for (int i = 0; i < k; ++i) {
    s.insert(v[i]);
}
print_set(s);
for (int i = 0; i < n-k; ++i) {
    s.erase(s.find(v[i]));
    s.insert(v[i+k]);
    cout << ",";
    print_set(s);
}

您可以尝试:http://ideone.com/mod3bg

所有操作与多键的复杂性是O(nlogk(。但是,不记得打印所有这些数据的复杂性是o(n*k(。

只是解决此问题的另一种方法:

  int k=4;
  std::vector<int> v = {8,4,7,5,1,10,3,9,2,6};
  std::multiset<int> ss;
  for(auto itr=v.begin();itr<v.end();itr++)
  {
    size_t remaining(std::distance(itr+k, v.end())); 
    std::cout<<remaining<<std::endl;
    ss.insert(itr,itr+k);
    print_set(ss);
    if(remaining==0)
      break;
    ss.clear();
  }