繁体   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