简体   繁体   中英

Fastest way to find pair in a vector, remove it while iterating

I am currently working on a greedy algorithm, which is similar to the Activity Selection Problem. I've got vector of pairs (natural numbers), sorted by second value. For each pair I take possibly closest pair(by closest i mean (p2.first - p1.second) is minimal and p1.second < p2.first ). Now I do some calculations with those values (doesn't matter), "increase" range of first pair from (p1.first,p1.second) to (p1.first, p2.second) and erase it. The algorithm will look for next closest pair to the new pair it just created with previous pair. My question is, what is the best (fastest) way to find such pairs without iterating over the list for each element. Also how shpuld I erase these pairs after calculations. I am using iterator to iterate over the list and when i remove these pairs it goes crazy so my workaround is to fill these wit (-1,-1) values but it is unacceptable because these algorithm is meant to go on Online Judge and it is way to slow.

Below is the example. Each column is index of pair, in each row is range of pair. For example pairs[0] = [0,3]. After first iteration pairs[0] should be transformed into [0,9] and the second column should be deleted.

在此处输入图片说明

It is really hard to say what the "fastest way" to do anything is. Even "fast enough" is problematic without knowing your constraints exactly. Therefore, I'm going to give you a few tips to get a (probably) "faster" program; whether it will be fast enough is up to you to decide.

First of all, you probably want to change your sort criterion. Instead of sorting on the second component (the end of the interval, I assume,) you need to sort on the first component and then on the second. This way, an interval that starts sooner will be earlier in the array, and among intervals with the same start, the one that is shortest will be first.

Secondly, you might want to have a helper data structure: a naturally-sorted array of pairs, where the first component of each pair is any number X and the second is the index of the first pair in the (sorted) original array that starts at X. For example, this array for the image in your question will be {{0, 0}, {4, 1}, {9, 2}}. It shouldn't be hard to see how to construct this array in O(n) and how to use it to accelerate your search over the original array to an amortized O(1).

Thirdly, to iterate over an std::vector and remove its elements without problems, you can use indexes instead of iterators. However, this is not particularly efficient, because each erase must shift quite a few elements backwards and might even reallocate the vector and copy/move all of its elements. Instead, do what your are doing now and mark those elements that your want removed with distinctive numbers, and after your algorithm is done, just go over the array one more time and remove them all. The following is a pseudo code:

displacement = 0
for all elements in the array, do:
    if current element should be removed, then:
        increment "displacement"
    else:
        move current element back "displacement" places

delete last "displacement" elements

EDIT : After reading your comment, you don't need any of this stuff. Just sort the array or pairs the way I wrote above (ie lexicographically), and then construct another array of pairs from it like this:

let original vector be A, and the new vector of pairs be B,
t0 = -1
t1 = -1
for all elements in A, do:
    if start time of current element is greater than "t1", then:
         append the pair (t0, t1) to B
         t0 = start time of current element
         t1 = end time of current element
    else:
         t1 = max(t1, end time of current element)
append the pair (t0, t1) to B
remove first element of B (because it is (-1, -1))

(My way is not exactly elegant, but it get's the job done.)

Then run your cost calculation logic on this new array, B. This new array will be shorter, and there will be no overlap between its elements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM