diff --git a/docs/algorithms/Scheduling Algorithms/SweepLine.md b/docs/algorithms/Scheduling Algorithms/SweepLine.md new file mode 100644 index 000000000..98fc083f6 --- /dev/null +++ b/docs/algorithms/Scheduling Algorithms/SweepLine.md @@ -0,0 +1,96 @@ +--- +id: sweep-line-algorithm +sidebar_position: 3 +title: Sweep Line Algorithm +sidebar_label: Sweep Line Algorithm +description: "This document explains the Merge Intervals problem using the Sweep Line Algorithm, including its description, approach, and implementation in C++." +tags: [leetcode, algorithms, problem-solving, sweep-line-algo] +--- + +# sweep-line-merge-intervals + +## Description +Given an array of intervals where `intervals[i] = [start_i, end_i]`, merge all overlapping intervals and return an array of the non-overlapping intervals that cover all the intervals in the input. + +### Example: +**Input**: `intervals = [[1,3],[2,6],[8,10],[15,18]]` +**Output**: `[[1,6],[8,10],[15,18]]` +**Explanation**: Since intervals [1,3] and [2,6] overlap, merge them into [1,6]. + +## Approach + +This approach uses a **sweep line algorithm**. Here's how it works: + +1. **Transform the intervals into events**: + - Each interval generates two events: one at the start and one at the end. A start event increases the "active" interval count, while an end event decreases it. +2. **Sort all events**: + - Sort events primarily by time. If two events have the same time, prioritize end events over start events. This ensures the correct merging of intervals. +3. **Sweep through the events**: + - Track when new intervals start and end based on active intervals, and merge intervals accordingly. + +## C++ Implementation + +```cpp +#include +#include +#include + +class Solution { +public: + std::vector> merge(std::vector>& intervals) { + // Step 1: Create events (start and end) from each interval + std::vector> events; + for (const auto& interval : intervals) { + events.push_back({interval[0], 1}); // Start event (+1) + events.push_back({interval[1], -1}); // End event (-1) + } + + // Step 2: Sort events. Sort by time, and if equal, end (-1) comes before start (+1) + std::sort(events.begin(), events.end(), [](const std::pair& a, const std::pair& b) { + if (a.first == b.first) return a.second < b.second; + return a.first < b.first; + }); + + // Step 3: Sweep through the events and merge intervals + std::vector> merged; + int active = 0; // Active intervals count + int start = -1; // Start of the current interval + + for (const auto& event : events) { + if (active == 0) { + // No active intervals, so this is the start of a new interval + start = event.first; + } + + // Update the active intervals count + active += event.second; + + if (active == 0) { + // When active becomes 0, we finished an interval + merged.push_back({start, event.first}); + } + } + + return merged; + } +}; + +int main() { + Solution sol; + std::vector> intervals = {{1, 3}, {2, 6}, {8, 10}, {15, 18}}; + + std::vector> result = sol.merge(intervals); + + for (const auto& interval : result) { + std::cout << "[" << interval[0] << "," << interval[1] << "] "; + } + + return 0; +} +``` + +## Time and Space Complexity +- **Time Complexity**:O(n log n), where n is the number of intervals. Sorting the events takes O(n log n), and the sweeping phase takes O(n). +- **Space Complexity**: O(n) due to the space used for storing events and the output merged intervals. + + diff --git a/docs/leetcode-Solutions/merge-intervals.md b/docs/leetcode-Solutions/merge-intervals.md new file mode 100644 index 000000000..6e54717dc --- /dev/null +++ b/docs/leetcode-Solutions/merge-intervals.md @@ -0,0 +1,62 @@ +--- +id: merge-intervals +sidebar_position: 3 +title: Merge Intervals +sidebar_label: Merge Intervals +description: "This document explains the Merge Intervals problem, including its description, approach, and implementation in C++." +tags: [leetcode, algorithms, problem-solving] +--- + +# merge-intervals + +## Description +Given an array of intervals where `intervals[i] = [start_i, end_i]`, merge all overlapping intervals and return an array of the non-overlapping intervals that cover all the intervals in the input. + +### Example: +**Input**: `intervals = [[1,3],[2,6],[8,10],[15,18]]` +**Output**: `[[1,6],[8,10],[15,18]]` +**Explanation**: Since intervals [1,3] and [2,6] overlap, merge them into [1,6]. + +## Approach +To merge overlapping intervals, the strategy is as follows: + +1. **Sort the intervals** by their start time. This helps ensure that when we traverse the intervals, we can compare each interval with the last merged one to check for overlaps. +2. **Iterate through the sorted intervals** and for each interval: + - If it overlaps with the last merged interval (i.e., if the current interval's start is less than or equal to the end of the last merged interval), merge them by updating the end time of the last merged interval to be the maximum of the current interval's end or the last merged interval's end. + - Otherwise, append the current interval to the result as a non-overlapping interval. +3. Finally, return the list of merged intervals. + +## C++ Implementation + +```cpp +#include +#include + +class Solution { +public: + std::vector> merge(std::vector>& intervals) { + // Step 1: Sort the intervals based on the starting times + std::sort(intervals.begin(), intervals.end(), [](const std::vector& a, const std::vector& b) { + return a[0] < b[0]; + }); + + std::vector> merged; + + // Step 2: Iterate over the intervals + for (const auto& interval : intervals) { + // If the merged list is empty or no overlap, append the interval + if (merged.empty() || merged.back()[1] < interval[0]) { + merged.push_back(interval); + } else { + // Step 3: If overlapping, merge the intervals + merged.back()[1] = std::max(merged.back()[1], interval[1]); + } + } + + return merged; + } +}; +``` + +Time Complexity: O(n log n) (due to sorting the intervals)
+Space Complexity: O(n) (for the output array) \ No newline at end of file