Touching segments

后端 未结 3 588
被撕碎了的回忆
被撕碎了的回忆 2020-12-30 16:19

Can anyone please suggest me algorithm for this.

You are given starting and the ending points of N segments over the x-axis. How many of these segments can be touch

相关标签:
3条回答
  • 2020-12-30 16:44

    Let assume that we have a data structure that supports the following operations efficiently:

    1. Add a segment.

    2. Delete a segment.

    3. Return the maximum number of segments that cover one point(that is, the "best" point).

    If have such a structure, we can get use the initial problem efficiently in the following manner:

    1. Let's create an array of events(one event for the start of each segment and one for the end) and sort by the x-coordinate.

    2. Add all segments to the magical data structure.

    3. Iterate over all events and do the following: when a segment start, add one to the number of currently covered segments and remove it from that data structure. When a segment ends, subtract one from the number of currently covered segment and add this segment to the magical data structure. After each event, update the answer with the value of the number of currently covered segments(it shows how many segments are covered by the point which corresponds to the current event) plus the maximum returned by the data structure described above(it shows how we can choose another point in the best possible way).

    If this data structure can perform all given operations in O(log n), then we have an O(n log n) solution(we sort the events and make one pass over the sorted array making a constant number of queries to this data structure for each event).

    So how can we implement this data structure? Well, a segment tree works fine here. Adding a segment is adding one to a specific range. Removing a segment is subtracting one from all elements in a specific range. Get ting the maximum is just a standard maximum operation on a segment tree. So we need a segment tree that supports two operations: add a constant to a range and get maximum for the entire tree. It can be done in O(log n) time per query.

    One more note: a standard segment tree requires coordinates to be small. We may assume that they never exceed 2 * n(if it is not the case, we can compress them).

    0 讨论(0)
  • 2020-12-30 16:47

    An O(N*max(logN, M)) solution, where M is the medium segment size, implemented in Common Lisp: touching-segments.lisp.

    The idea is to first calculate from left to right at every interesting point the number of segments that would be touched by a line there (open-left-to-right on the lisp code). Cost: O(NlogN)

    Then, from right to left it calculates, again at every interesting point P, the best location for a line considering segments fully to the right of P (open-right-to-left on the lisp code). Cost O(N*max(logN, M))

    Then it is just a matter of looking for the point where the sum of both values tops. Cost O(N).

    The code is barely tested and may contain bugs. Also, I have not bothered to handle edge cases as when the number of segments is zero.

    0 讨论(0)
  • 2020-12-30 16:51
    1. The problem can be solved in O(Nlog(N)) time per test case.

    2. Observe that there is an optimal placement of two vertical lines each of which go through some segment endpoints

    3. Compress segments' coordinates. More info at What is coordinate compression?

    4. Build a sorted set of segment endpoints X

    5. Sort segments [a_i,b_i] by a_i

    6. Let Q be a priority queue which stores right endpoints of segments processed so far

    7. Let T be a max interval tree built over x-coordinates. Some useful reading atWhat are some sources (books, etc.) from where I can learn about Interval, Segment, Range trees?

    8. For each segment make [a_i,b_i]-range increment-by-1 query to T. It allows to find maximum number of segments covering some x in [a,b]

    9. Iterate over elements x of X. For each x process segments (not already processed) with x >= a_i. The processing includes pushing b_i to Q and making [a_i,b_i]-range increment-by-(-1) query to T. After removing from Q all elements < x, A= Q.size is equal to number of segments covering x. B = T.rmq(x + 1, M) returns maximum number of segments that do not cover x and cover some fixed y > x. A + B is a candidate for an answer.

    Source: http://www.quora.com/What-are-the-intended-solutions-for-the-Touching-segments-and-the-Smallest-String-and-Regex-problems-from-the-Cisco-Software-Challenge-held-on-Hackerrank

    0 讨论(0)
提交回复
热议问题