algorithm - 交换后的排序检查

标签 algorithm sorting c++11

所以我有一个任务有问题。

您已经给出了数字序列和 n 个操作,每个操作有两个数字(此给定序列中的索引)。

您必须检查每个操作后的序列是否排序。 (应用每个操作)。

我的问题是我的解决方案太慢了。它在 O(n^2) 中起作用。 (我只是进行交换并使用 c++11 中的 is_sorted)。如何让它更快?

提前致谢

最佳答案

我认为你的意思是你有一个序列,比如说...

3, 9, 34, 8, 5, 25, 10

还有一个交换两个数字的操作,所以 swap[2, 4](当然是零索引)会产生

3, 9, 5, 8, 34, 25, 10

即使操作不交换,而是执行一些仅作用于这两个数字的其他操作,该算法仍然有效;事实上,这将适用于更改该数组中任何数字的任何内容:

首先,我会保留一个 bool 值辅助数组,它告诉我序列中的每个成员是否大于它前面的数字,表明这个数字相对于它前面的数字是否就位或按顺序排列。然后,我还会计算这些 bool 值中有多少是真的。当适当的数字计数等于序列中的项目数时,序列被排序。当对序列中的任何数字进行更改时,我会使用以下算法进行检查:

float MySequence[LengthOfSequence];
bool IsNumInPlace[LengthOfSequence];
int CountOfNumsInPlace;

... something loads MySequence ...

// this starts that helper array of booleans
IsNumInPlace[0] = true;
CountOfNumsInPlace = 1;
for (i = 1; i < LengthOfSequence; i++) {
   IsNumInPlace[i] = (MySequence[i] > MySequence[i-1]);
   if (IsNumInPlace[i]) CountOfNumsInPlace++;
}


... something changes item at index "x" in the sequence ...
// whether this number, and possibly the one after it, are in place, needs
// to be rechecked
CheckThisItem(x);
if (x < LengthOfSequence - 1) CheckThisItem(x + 1);

... the array is sorted, at this point, if CountOfNumsInPlace is equal to the number of items in the array ...

关键在于这个小函数,它根据给定索引处的值是否大于或等于它之前的项目的值来增加或减少“就地项目”的数量。

private void CheckThisItem(int ItemChanged) {
    bool IsNewNumInPlace= (ItemChanged == 0) ||
                          (MySequence[ItemChanged] >= MySequence[ItemChanged - 1]);
    if (IsNumInPlace[ItemChanged] && !IsNewNumInPlace) {
        CountOfNumsInPlace--;
    } else if (!IsNumInPlace[ItemChanged] && IsNewNumInPlace) {
        CountOfNumsInPlace++;
    }
    IsNumInPlace[ItemChanged] = IsNewNumInPlace;
}

这应该会为您提供一个 O(n) 的算法。您不会将数组中的每个项目与其周围的项目进行重新比较,以查看该数组是否按顺序排列,即使是那些没有受到影响的项目。您只是将更改的项目与它之前的项目和之后的项目进行比较。

请注意,数组中的第一项相对于它之前的项被认为是“就位”的。因为它前面没有项目(它是第一个),所以没有什么不合适的,所以就排序而言它是“好的”。

如果您的操作对序列中的两个项目进行了更改,那么只需将最后一部分执行两次,每个更改的数字一次。

关于algorithm - 交换后的排序检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47517239/

相关文章:

c++ - 递归调用模板函数 (C++)

c++ - 我怎样才能有模板化的 friend ?

python - 对多个参数运行算法的最快方法,过去曾在更改一个变量后运行过该算法

algorithm - 家庭作业 - 大 O 符号和计算时间

javascript - Knockout.js:对多个键进行排序

python - 匹配并插入到Python排序列表中

c++ - enable_shared_from_this 需要什么?

algorithm - 查找集合中哪些范围与某个指定范围有非空交集

java - 如何在一个循环中重新组合这些 if 条件?

Python - 如何对字母和数值列表进行排序?