c++代码缓慢且超过时间限制

标签 c++ algorithm sorting

段的起点和终点在 vector startsends 中给出。 vector 点中给出了点列表。任务是找到包含每个点的段数。

在我的解决方案中,startendpoint 的每个元素分别被赋予标签 l、p 和 r,并存储在 vector Pairs vector 首先按第一个元素排序,然后按第二个元素排序。最后,我遍历 pairs vector 并递增一个变量 coverage 如果它是一个起点,如果它是一个终点则递减它,如果它是一个点则将 coverage 的值分配给答案。< br/>
该算法似乎是正确的,时间复杂度为 O(nlog(n)),但它超出了时间限制。代码的哪一部分很慢?
代码:

vector<int> fast_count_segments(vector<int>& starts, vector<int>& ends, vector<int>& points) {
    vector<int> cnt(points.size());
    const int left_label = 1, point_label = 2, right_label = 3;
    std::map<int, std::set<int>> orig_point_map;
    vector<pair<int,int>> pairs(2*starts.size()+points.size());
    int k = 0;
    for (auto& i : starts)
    {
        pairs[k++] = std::make_pair(i, left_label);
    }
    for (auto& i : ends)
    {
        pairs[k++] = std::make_pair(i, right_label);
    }
    for (auto i = 0;i < points.size();i++)
    {
        int point = points[i];
        pairs[k++] = std::make_pair(point, point_label);
        orig_point_map[point].emplace(i);
    }

    std::sort(pairs.begin(), pairs.end());
    int coverage = 0;
    for (auto& x : pairs) {
        if (x.second == 1) {
            coverage++;
        }
        else if (x.second == 3) {
            coverage--;
        }
        else {
            std::set<int> indices = orig_point_map[x.first];
            for(auto i : indices) {
                cnt[i] = coverage;
            }
        }
    }
    return cnt;
}

最佳答案

虽然复杂性很好,但您创建了很多本可以避免的拷贝。 您可以使用修改后的版本:

std::vector<int> fast_count_segments(std::vector<int> starts,
                                     std::vector<int> ends,
                                     const std::vector<int>& points) {
    std::vector<int> cnt(points.size());
    std::vector<std::pair<int, int>> pairs(points.size());

    for (auto i = 0u; i != points.size(); ++i) {
        pairs[i] = std::make_pair(points[i], i);
    }
    std::sort(starts.begin(), starts.end());
    std::sort(ends.begin(), ends.end());
    std::sort(pairs.begin(), pairs.end());
    int coverage = 0;
    auto it_start = starts.begin();
    auto it_end = ends.begin();
    for (auto& x : pairs) {

        while (it_start != starts.end() && *it_start <= x.first) {
            ++it_start;
            ++coverage;
        }
        while (it_end != ends.end() && *it_end < x.first) {
            ++it_end;
            --coverage;
        }
        cnt[x.second] = coverage;     
    }
    return cnt;
}

关于c++代码缓慢且超过时间限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41161046/

相关文章:

c++ - LLVM比较两个函数的参数

c++ - POST HTTP 请求以使用 Java 脚本和 C++ 使用用户名和密码登录

c++ - 在 Excel 自动化中使用非本地化公式

PHP 更快的素数生成器

c# - 将数字列表分组为类似数字的固定集合(首选循环移位)

javascript - 叠瓦式 javascript for 循环的简化

c++ - 不完整类型 C++

c++ - 添加到简单链接列表的前面

在内存中布置有向无环图以最大化数据局部性的算法

php - 对包含 SQL 查询数据的表中的非 SQL 表列进行排序