leetcode

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit b2340319622126515c448a1e4c6f06ef5f0aa2e6
parent 9fa4140dfba7b609151b5fd99c4ae7a0f65ae42f
Author: Andrew Laack <andrew@laack.co>
Date:   Mon, 14 Jul 2025 08:35:17 -0500

Completed non overlapping intervals

Diffstat:
Mmerge-intervals/merge-intervalsV1.py | 11+++++++----
Anon-overlapping-intervals/non-overlapping-intervalsV1.py | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/merge-intervals/merge-intervalsV1.py b/merge-intervals/merge-intervalsV1.py @@ -5,18 +5,19 @@ # TC: O(nlogn) + class Solution: def merge(self, intervals: List[List[int]]) -> List[List[int]]: - + intervals.sort() merged = [] for i in range(0, len(intervals)): current = intervals[i] - if len(intervals) - 1 != i and overlapping(intervals[i], intervals[i+1]): - current = merge(intervals[i], intervals[i+1]) - + if len(intervals) - 1 != i and overlapping(intervals[i], intervals[i + 1]): + current = merge(intervals[i], intervals[i + 1]) + if merged and overlapping(merged[-1], current): merged[-1] = merge(merged[-1], current) else: @@ -24,10 +25,12 @@ class Solution: return merged + # int1[0] <= int2[0] def overlapping(int1, int2): if int1[1] >= int2[0]: return True + def merge(int1, int2): return [min(int1[0], int2[0]), max(int1[1], int2[1])] diff --git a/non-overlapping-intervals/non-overlapping-intervalsV1.py b/non-overlapping-intervals/non-overlapping-intervalsV1.py @@ -0,0 +1,62 @@ +# INTUITION: + +# merge intervals to ensure they are non-overlapping +# return difference in list size from start to merged list + +# LESS MEMORY? +# SMALL CONSTANT FACTORS? + +# we might be able to use constant memory by doing our upper and lower comparisons in place + +# APPROACH + +# 1) Sort list by start ascending +# 2) Perform pseudo-merge (this can allow less memory usage than true) +# a) loop through each element +# i) if lower > uppermost found: +# set uppermost found +# don't increment infraction counter +# ii) if lower < uppermost found: +# set uppermost found to be max(prior, current_upper) +# increment infraction counter +# 3) Return infraction counter + +# PROBLEM W/ APPROACH: + +# This may not be the optimal removal approach +# instead of above we could try removing the interval with the highest +# max at each infraction step. + +# === + +# as we go track all uppers that we've found, in a heap +# pop the heap whenever we need to remvoe an interval to ensure this works correctly +# we then check to see if there are other elements invalidating the current one +# if there are we remove them as well. +# we then insert the current upper and continue. + +# TC: +# nlogn - sort +# nlogn - worst case at a step +# logn - ac for step + +# WCATC - nlogn + +import heapq + + +class Solution: + def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int: + + intervals.sort(key=lambda x: x[-1]) + uppers = [] + removed = 0 + + for interval in intervals: + if len(uppers) > 0 and interval[0] < -uppers[0]: + removed += 1 + continue + + heapq.heappush(uppers, -interval[1]) + + return removed