合併、刪除區間演算法C++程式碼

mariocanfly發表於2024-10-09
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
class Solution {
  public:
    const int COMBINE_INT = 0; // 1表示整數點區間,比如[1:3]和[4:5]會合併為[1:5], 0則僅會合並[1:3]和[3:4]這類的區間。
    vector<pair<int, int>> interval;
    Solution() {}

    //用於手工新增全部區間後,統一合併
    void MergeAndSortInterval() {
        sort(interval.begin(), interval.end(), [](const auto &a, const auto &b) { return a.first < b.first; });
        for (int i = 0; i < interval.size() - 1; ++i) {
            if (interval[i].second >= interval[i + 1].first - COMBINE_INT) {
                interval[i].second = max(interval[i].second, interval[i + 1].second);
                interval.erase(interval.begin() + i + 1);
                --i;
            }
        }
    }
    //新增區間
    void AddInterval(const int left, const int right) {
        const auto it = lower_bound(interval.begin(), interval.end(), left,
                                    [](const pair<int, int> &p, const int left) { return p.first < left; });
        int i = max(0, int(distance(it, interval.begin())) - 1);
        if (it == interval.end()) {
            interval.push_back({left, right});
        } else {
            interval.insert(it, {left, right});
        }
        for (; i < interval.size() - 1; ++i) {
            if (interval[i].second >= interval[i + 1].first - COMBINE_INT) {
                interval[i].second = max(interval[i].second, interval[i + 1].second);
                interval.erase(interval.begin() + i + 1);
                --i;
            }
        }
    }
    //刪除區間
    void DeleteInterval(const int left, const int right) {
        for (int i = 0; i < interval.size(); ++i) {
            if (left <= interval[i].first && interval[i].second <= right) {
                interval.erase(interval.begin() + i);
                --i;
            } else if (left <= interval[i].first && interval[i].first <= right) {
                interval[i].first = right + COMBINE_INT;
            } else if (left <= interval[i].second && interval[i].second <= right) {
                interval[i].second = left - COMBINE_INT;
            } else if (interval[i].first < left && right < interval[i].second) {
                const int newRight = interval[i].second;
                interval[i].second = left - COMBINE_INT;
                interval.insert(interval.begin() + i + 1, {right + COMBINE_INT, newRight});
            }
        }
    }
    //輸出展示
    void Output() const {
        for (const auto p : interval) {
            cout << p.first << ":" << p.second << ", ";
        }
        cout << endl;
    }
};

int main() {
    Solution a;
    a.AddInterval(0, 10);
    a.AddInterval(3, 10);
    a.AddInterval(5, 13);
    a.AddInterval(4, 30);
    a.DeleteInterval(10, 20);
    a.AddInterval(4, 6);
    a.DeleteInterval(2, 3);
    a.DeleteInterval(1, 4);
    a.Output();
    return 0;
}

相關文章