1+ /*
2+ * Interval Scheduling Algorithm (Greedy Approach)
3+ *
4+ * Description:
5+ * The Interval Scheduling algorithm selects the maximum number of non-overlapping intervals
6+ * from a given set of intervals. It follows a greedy approach by:
7+ * 1. Sorting all intervals by their finishing times
8+ * 2. Selecting the interval with earliest finish time
9+ * 3. Discarding all intervals that overlap with the selected one
10+ * 4. Repeating steps 2-3 until no more intervals remain
11+ *
12+ * Time Complexity: O(n log n) - dominated by the sorting operation
13+ * Space Complexity: O(n) - to store the intervals and results
14+ */
15+
16+ #include < iostream>
17+ #include < vector>
18+ #include < algorithm>
19+
20+ using namespace std ;
21+
22+ // Structure to represent an interval with start and finish times
23+ struct Interval {
24+ int start;
25+ int finish;
26+ int id; // To identify the original position of the interval
27+
28+ // Constructor
29+ Interval (int s, int f, int i) : start(s), finish(f), id(i) {}
30+ };
31+
32+ // Function to print the intervals
33+ void printIntervals (const vector<Interval>& intervals) {
34+ cout << " Intervals: " << endl;
35+ for (const auto & interval : intervals) {
36+ cout << " (" << interval.start << " , " << interval.finish << " ) ID: " << interval.id << endl;
37+ }
38+ }
39+
40+ // Function to find the maximum number of non-overlapping intervals
41+ vector<Interval> intervalScheduling (vector<Interval>& intervals) {
42+ // If no intervals, return empty result
43+ if (intervals.empty ()) {
44+ return {};
45+ }
46+
47+ // Sort intervals by finish time
48+ sort (intervals.begin (), intervals.end (),
49+ [](const Interval& a, const Interval& b) {
50+ return a.finish < b.finish ;
51+ });
52+
53+ // Vector to store selected intervals
54+ vector<Interval> result;
55+
56+ // Select the first interval (with earliest finish time)
57+ result.push_back (intervals[0 ]);
58+
59+ // Last selected interval's finish time
60+ int lastFinishTime = intervals[0 ].finish ;
61+
62+ // Iterate through remaining intervals
63+ for (size_t i = 1 ; i < intervals.size (); i++) {
64+ // If current interval's start time is >= last selected interval's finish time
65+ if (intervals[i].start >= lastFinishTime) {
66+ // Select this interval
67+ result.push_back (intervals[i]);
68+ // Update last finish time
69+ lastFinishTime = intervals[i].finish ;
70+ }
71+ }
72+
73+ return result;
74+ }
75+
76+ // Main function with test cases
77+ int main () {
78+ // Test Case 1: Basic example
79+ cout << " Test Case 1:" << endl;
80+ vector<Interval> intervals1 = {
81+ {1 , 3 , 1 }, // (start, finish, id)
82+ {2 , 5 , 2 },
83+ {3 , 9 , 3 },
84+ {6 , 8 , 4 },
85+ {5 , 7 , 5 }
86+ };
87+
88+ printIntervals (intervals1);
89+ vector<Interval> result1 = intervalScheduling (intervals1);
90+
91+ cout << " \n Selected intervals:" << endl;
92+ printIntervals (result1);
93+ cout << " Maximum number of non-overlapping intervals: " << result1.size () << endl;
94+
95+ // Test Case 2: All intervals overlap
96+ cout << " \n Test Case 2:" << endl;
97+ vector<Interval> intervals2 = {
98+ {1 , 10 , 1 },
99+ {2 , 6 , 2 },
100+ {3 , 8 , 3 },
101+ {4 , 9 , 4 }
102+ };
103+
104+ printIntervals (intervals2);
105+ vector<Interval> result2 = intervalScheduling (intervals2);
106+
107+ cout << " \n Selected intervals:" << endl;
108+ printIntervals (result2);
109+ cout << " Maximum number of non-overlapping intervals: " << result2.size () << endl;
110+
111+ // Test Case 3: No overlapping intervals
112+ cout << " \n Test Case 3:" << endl;
113+ vector<Interval> intervals3 = {
114+ {1 , 2 , 1 },
115+ {3 , 4 , 2 },
116+ {5 , 6 , 3 },
117+ {7 , 8 , 4 }
118+ };
119+
120+ printIntervals (intervals3);
121+ vector<Interval> result3 = intervalScheduling (intervals3);
122+
123+ cout << " \n Selected intervals:" << endl;
124+ printIntervals (result3);
125+ cout << " Maximum number of non-overlapping intervals: " << result3.size () << endl;
126+
127+ return 0 ;
128+ }
0 commit comments