簡體   English   中英

合並重疊區間 C++ 問題解決

[英]Merge Overlapping intervals C++ problem solving

問題來自InterviewBit(編碼網站):

給定一組區間,合並所有重疊區間。 例如:

給定:[1,3],[2,6],[8,10],[15,18]

返回:[1,6],[8,10],[15,18]。

確保返回的間隔已排序。

我希望我的邏輯是正確的,但是我在代碼中遇到了錯誤。 也許是因為我沒有正確使用向量? 我的代碼是:

vector<Interval> Solution::merge(vector<Interval> &A) {
    // Do not write main() function.
    // Do not read input, instead use the arguments to the function.
    // Do not print the output, instead return values as specified
    // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details
    vector<int> mergedIntervals;
    if(A.size()==0){
        return A;
    }
    sort(A.begin(),A.end());
    //temp vector to store first ele 
    vector<int> tempInterval=A[0];
    
    //merge operation
    for(auto it: A){
        if(it[0]<tempInterval[1]){
            tempInterval[1]=max(it[1],tempInterval[1]);
        }
        else{
            mergedIntervals.push_back(tempInterval);
            tempInterval=it;
        }
        mergedIntervals.push_back(tempInterval);
        return mergedIntervals;
    }
    
}
/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */

錯誤:

Compiling your Code...
> Error!
solution.cpp: In member function 'std::vector<Interval> Solution::merge(std::vector<Interval>&)':

solution.cpp:21:33: error: conversion from '__gnu_cxx::__alloc_traits<std::allocator<Interval>, Interval>::value_type' {aka 'Interval'} to non-scalar type 'std::vector<int>' requested

   25 |     vector<int> tempInterval=A[0];

      |                                 ^

solution.cpp:25:14: error: no match for 'operator[]' (operand types are 'Interval' and 'int')

   29 |         if(it[0]<tempInterval[1]){

      |              ^

solution.cpp:26:35: error: no match for 'operator[]' (operand types are 'Interval' and 'int')

   30 |             tempInterval[1]=max(it[1],tempInterval[1]);

      |  

                             ^

等等..

你可以做得更好:

首先,按值接受向量——這會在開始時創建一個版權:

vector<Interval> Solution::merge(vector<Interval> data)
// (note the dropped ampersand!)

然后你可以合並這個副本的間隔! 如果您不應該被允許或以其他方式被阻止進行該修改(無法訪問用於測試的標頭),那么您可以(並且只有這樣您應該)簡單地創建參數的副本並繼續那個:

vector<Interval> Solution::merge(vector<Interval>& source)
{
    std::vector data(source); // just create a copy as very first step
                              // and continue operating on this...
    // ...

您仍然需要排序,但我假設您沒有為Interval類提供自定義operator< (我也不會這樣做,因為要求可能會根據具體用例而發生很大變化),所以您可以提供適當的比較器明確:

std::sort
(
    data.begin(), data.end(),
    [](Interval const& x, Interval const& y)
    {
        return x.begin < y.begin;
    }
);

最后,如前所述,您現在可以通過僅保留合並的元素(類似於std::remove / std::remove_if do)就地合並:

auto cur = data.begin();
for(auto i = cur; i != data.end(); ++i)  // you could start with cur + 1, too, but
                                         // that would require special handling
                                         // for the empty vector... 
{
    if(i->begin <= cur->end)
    {
        // intervals overlap (or touch) -> need to merge!
        cur->end = std::max(cur->end, i->end); // enlarges the interval, if need be
    }
    else
    {
        // no overlap any more, need to start a new interval
        // -> copy current towards front (note: there might be a gap
        //    due to already merged intervals!)
        *++cur = std::move(*i);
        // (moving is always correct, but not necessary HERE as identical to
        // copying anyway – I recommend still adding it by principle to get
        // used to when re-using the pattern elsewhere)
    }
}

現在 cur 指向要保留的最后一個元素,我們還需要刪除 // 多余的元素(這稱為erase-remove-idiom ):

data.erase(++cur, data.end()); // note: need to increment to point BEHIND
                               // the last element to be retained!

您需要做的就是返回以這種方式接收到的向量;)

最后注意事項:

  • 這是完全未經測試的代碼——如果您發現錯誤,請自行修復。
  • 此代碼假定間隔已經被規范化(就像您的原始版本一樣) - 如果您不能期望這是前提條件,您可能需要添加代碼來修復(如果后者小於前者,則交換beginend成員)。

當我將vector<int>更改為Interval時,我得到了這個:

#include <vector>
#include <algorithm>
using namespace std; // this is bad but all the stupid sites open std

struct Interval {
     int start;
     int end;
     Interval() : start(0), end(0) {}
     Interval(int s, int e) : start(s), end(e) {}
};

vector<Interval> merge(vector<Interval> &A) {
    // Do not write main() function.
    // Do not read input, instead use the arguments to the function.
    // Do not print the output, instead return values as specified
    // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details
    vector<Interval> mergedIntervals;
    if (A.size()==0){
        return A;
    }
    sort(A.begin(), A.end(),
         [](const Interval &lhs, const Interval &rhs) {
            return lhs.start < rhs.start;
        });
    //temp vector to store first ele 
    Interval tempInterval=A[0];
    
    //merge operation
    for (const auto &it: A){
        if (it.start<tempInterval.end) {
            tempInterval.end=max(it.end,tempInterval.end);
        } else {
            mergedIntervals.push_back(tempInterval);
            tempInterval=it;
        }
        mergedIntervals.push_back(tempInterval);
    }
    return mergedIntervals;    
}

唯一棘手的一點是 Interval 缺少operator<因此您必須為sort提供比較。

您可以通過在mergedIntervals中保留空間來改進這一點,或者甚至更好地在A中就地執行它並修剪A以適應。

很明顯,你永遠都不應該寫出這樣的函數簽名。 利用:

vector<Interval> merge(const vector<Interval> &A);
vector<Interval> merge(vector<Interval> &&A);
void merge_in_place(vector<Interval> &A);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM