如何通过一组线段找到最大交点数

时间:2011-05-17 21:03:25

标签: c++ algorithm

假设我在笛卡尔坐标系中给出了线段的数量。每条线给出为[x0,y0]和[x1,y1]。算法应该找到一条垂直的交叉最大行数。 在这个例子中,它跨越了四行:

enter image description here

什么算法能以最小的复杂度做到这一点?(我更喜欢c ++,但某些伪代码也可以)

P.S需要考虑的是多条线在同一个x坐标中开始/结束

谢谢。

3 个答案:

答案 0 :(得分:9)

  1. 为每个段将每一行转换为[x_start,x_end]的间隔。
  2. 创建一个数据结构,其中包含一个标志,指示它是起点还是终点,以及点值。
  3. 对所有点进行排序,然后迭代它们,当您点击起点时递增计数器,并在达到终点时递减计数器。跟踪最大值。
  4. 如果需要,请重复Y值。
  5. O(n lg n)时间复杂度

答案 1 :(得分:1)

如果你想要垂直,那么这里不需要y。算法如下。

  1. 将行排序为x0低于x1
  2. 将所有点放在已排序的orden中的单独数组中,并使用点存储标记,该标志指示该点是行的开头还是结尾
  3. 在数组上运行并获取属于最大给定间隔数的段

    vector<pair<double, unsigned char> > points; // (point, flag) pairs
    //read [x0, x1]s to points, be sure that x0 <= x1 (swap them otherwise)
    //0 for x0, 1 for x1
    sort(points.begin(), points.end());
    int ans = 0;
    int curstate = 0;
    for(int i = 0; i < points.size(); ++i)
    {
        if(points[i].second == 0)
            ++curstate;
        else
            --curstate;
        ans = max(ans, curstate);
    }
    

答案 2 :(得分:0)

遍历现有行的combinations。为每个迭代构建一个列表,其中包含当前行不perpendicular的所有其他行。按大小按列降序排列列表。具有最大尺寸的(第一)列表将是解决方案。它将包含一个交叉的行列表。有无限数量的线可以作为解决方案。把你的一些工资作为特许权使用费寄给我;)