[英]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!
您需要做的就是返回以这种方式接收到的向量;)
最后注意事项:
begin
和end
成员)。当我将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.