Intervals are often given in random order. Why is sorting intervals by their start time a common first step in solving interval problems?
Think about how processing intervals in order helps to compare them easily.
Sorting intervals by start time allows us to check each interval against the previous one to find overlaps or gaps efficiently. Without sorting, intervals are scattered and comparisons become complex.
What is the output of the following Go code that merges overlapping intervals?
package main import ( "fmt" "sort" ) type Interval struct { start, end int } func mergeIntervals(intervals []Interval) []Interval { sort.Slice(intervals, func(i, j int) bool { return intervals[i].start < intervals[j].start }) merged := []Interval{} for _, interval := range intervals { if len(merged) == 0 || merged[len(merged)-1].end < interval.start { merged = append(merged, interval) } else { if merged[len(merged)-1].end < interval.end { merged[len(merged)-1].end = interval.end } } } return merged } func main() { intervals := []Interval{{1,3}, {2,6}, {8,10}, {15,18}} result := mergeIntervals(intervals) for _, iv := range result { fmt.Printf("%d->%d ", iv.start, iv.end) } }
Look at how overlapping intervals are merged by extending the end time.
The intervals {1,3} and {2,6} overlap, so they merge into {1,6}. The others do not overlap and remain as is.
What error does the following Go code produce when checking if two intervals overlap?
package main import "fmt" type Interval struct { start, end int } func isOverlap(a, b Interval) bool { return a.end > b.start && a.start < b.end } func main() { a := Interval{1, 5} b := Interval{5, 10} fmt.Println(isOverlap(a, b)) }
Check if intervals that just touch at the boundary count as overlapping.
The function returns false because the intervals only touch at point 5 but do not overlap. The condition uses '>' and '<' which excludes touching intervals.
What is the output of this Go code that inserts a new interval into a list and merges overlaps?
package main import ( "fmt" "sort" ) type Interval struct { start, end int } func insertInterval(intervals []Interval, newInterval Interval) []Interval { intervals = append(intervals, newInterval) sort.Slice(intervals, func(i, j int) bool { return intervals[i].start < intervals[j].start }) merged := []Interval{} for _, interval := range intervals { if len(merged) == 0 || merged[len(merged)-1].end < interval.start { merged = append(merged, interval) } else { if merged[len(merged)-1].end < interval.end { merged[len(merged)-1].end = interval.end } } } return merged } func main() { intervals := []Interval{{1,2}, {3,5}, {6,7}, {8,10}, {12,16}} newInterval := Interval{4,8} result := insertInterval(intervals, newInterval) for _, iv := range result { fmt.Printf("%d->%d ", iv.start, iv.end) } }
Focus on how the new interval merges with existing overlapping intervals.
The new interval {4,8} overlaps with {3,5}, {6,7}, and {8,10}, merging them into {3,10}. The others remain separate.
Intervals are a common pattern in many problems. Why are interval problems especially important in scheduling and resource allocation?
Think about what intervals represent in real life scheduling.
Intervals represent periods when resources or time slots are used. Detecting overlaps helps avoid conflicts and optimize resource use.
