[英]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.