這個題目比較簡單,首先將給定的區間排序,在對重合的區間進行排序,使得區間變成遞增且不重疊的若干個區間,對於給定的區間在已經處理好的區間內進行二分查找,完成區間覆蓋的判斷。
程序如下:
#include <stdio.h>
#include <vector>
#include <algorithm>
class Interval {
public:
Interval(int start, int end) : start_(start), end_(end) {}
Interval() :start_(0), end_(0) {}
static bool OrderByStart(const Interval& left, const Interval& right) {
return left.start_ < right.start_;
}
friend bool operator<(const Interval& left, const Interval& right) {
return left.start_ < right.start_;
}
int start_;
int end_;
};
void CombinInterval(std::vector<Interval>& orginal, std::vector<Interval>* combined) {
if (orginal.size() < 1) {
return;
}
sort(orginal.begin(), orginal.end(), Interval::OrderByStart);
Interval combined_interval = orginal[0];
int new_ending = orginal[0].end_;
for (int i = 1; i < orginal.size(); ++i) {
if (combined_interval.end_ >= orginal[i].start_) {
new_ending = combined_interval.end_ > orginal[i].end_ ? combined_interval.end_ : orginal[i].end_;
continue;
}
combined_interval.end_ = new_ending;
combined->push_back(combined_interval);
combined_interval = orginal[i];
new_ending = orginal[i].end_;
}
combined_interval.end_ = new_ending;
combined->push_back(combined_interval);
}
bool CoverTest(const Interval& interval, std::vector<Interval>& intervals, Interval* covered_interval) {
std::vector<Interval> combined_intervals;
CombinInterval(intervals, &combined_intervals);
for (int i = 0; i < combined_intervals.size(); ++i) {
printf("%d-%d\n", combined_intervals[i].start_, combined_intervals[i].end_);
}
if (combined_intervals.size() < 1) {
return false;
}
int start = 0;
int end = combined_intervals.size() -1;
int middle = 0;
bool found = false;
while (end >= start) {
middle = (start + end) / 2;
if (interval < combined_intervals[middle]) {
end = middle - 1;
} else if (combined_intervals[middle] < interval) {
start = middle + 1;
} else {
found = true;
break;
}
}
int target_index = found ? middle : start - 1;
printf("target:%d\n", target_index);
if (target_index >= 0 &&
combined_intervals[target_index].start_ <= interval.start_ &&
combined_intervals[target_index].end_ >= interval.end_) {
*covered_interval = combined_intervals[target_index];
return true;
} else {
return false;
}
}
int main(int argc, char** argv) {
std::vector<Interval> intervals;
intervals.push_back(Interval(2,5));
intervals.push_back(Interval(3,4));
intervals.push_back(Interval(4,7));
intervals.push_back(Interval(9,13));
Interval target_interval(3, 4);
Interval covered_interval;
if (CoverTest(target_interval, intervals, &covered_interval)) {
printf("the covered interval is (%d, %d)\n", covered_interval.start_, covered_interval.end_);
} else {
printf("uncovered\n");
}
}
程序編寫時開始犯了幾個錯誤:
1、函數參數開始使用了const 修飾,導致sort時出錯
2、區間合併時,沒有將最後一個加入到向量中,new_ending設置的初值也要注意,開始就出錯了
3、二分查找,找下界時,需要將查找過程走幾遍就比較清楚了,下界是start-1,但如果start爲0,下界可能是負數,要注意處理。另外循環條件是start <=end,等號也很重要,如果判斷過程中只有一個元素時,就是等號覆蓋的情況。
參考文獻:
編程之美2.19