有可能在线性时间内进行一般排序吗

Is it possible to generically sort in linear time?

本文关键字:排序 线性 时间 有可能      更新时间:2023-10-16

我试图在O(n)时间内解决一个问题,在这个问题中,给定容器前面和容器后面的两个前向迭代器,我想删除容器中所有没有出现的元素;这个次数>。例如,给定一个字符串向量,如("john"、"hello"、"one"、"yes"、"hello"、"one"),并且我想删除所有出现次数少于2次的元素,那么我的最终向量将只包含("hello,"one")。

我在想,如果我能在O(n)时间内进行一般排序,我就可以(在O(n)时间内)完成这个结果,但我很难用字符串、int、chars或其他任何可能使用的东西(一般)来做到这一点。我想得对吗,还是有更简单的方法来解决这个问题?

是的,您实际上并不是在排序,而是在删除元素。

1) 。将每个单词存储到一个哈希集中。2) 。查找并仅在不在哈希集中时添加。

简短回答:否。基于比较的排序需要O(n log n)时间。(这可以被正式证明。)如果你对你的输入有所了解(例如,输入在已知范围内随机均匀分布),那么你可以在O(n)时间内使用众所周知的算法,如桶排序或基数排序。与@MooingDuck相反,在O(1)时间中不存在排序(这应该是显而易见的——对于任何排序算法,您必须至少访问每个元素一次)。

然而,正如其他几张海报所指出的,你的问题不需要排序算法。。。

无需对进行排序

1) 填充std::unordered_map<string,vector<int>> indexOfStrings;-O(N)

2) 对于其vector size() < 2的每个string,删除元素-O(删除次数)<=O(N)

indexOfStrings-存储字符串每次出现的索引。这允许在不需要搜索的情况下从矢量中快速删除。

您不需要排序,只需要unordered_map:

unordered_map<string, int> counter;
vector<string> newvec;
for(string &s : v) {
    if((++counter[s]) == 2) {
        newvec.push_back(s);
    }
}

请注意,这是C++11代码。(感谢@jogojapan提供的代码改进建议)。