Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- 쉬움
- linked list
- DP
- two pointers
- dfs
- 미디움
- Binary
- 중간
- 리트코드
- binary search
- Array
- Python
- list
- math
- 이진트리
- 재귀
- HashTable
- Depth-first Search
- string
- backtracking
- leetcode
- recursive
- sorting
- binary tree
- hash table
- 문자열
- tree
- Medium
- matrix
- easy
Archives
- Today
- Total
부부의 코딩 성장 일기
LeetCode 56(Merge Intervals, Python) 본문
1. 문제 링크
Merge Intervals - LeetCode
Can you solve this real interview question? Merge Intervals - Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input
leetcode.com
2. 문제 설명
- 구간을 나타내는 리스트들이 주어졌을 때 겹치는 리스트가 있다면 이를 합쳐서 반환하는 문제
- 예시) intervals = [[1,3],[2,6],[8,10],[15,18]]가 주어지면 [1,3]과 [2,6]은 겹치므로 이를 [1,6]으로 바꾸어 [[1,6],[8,10],[15,18]]를 반환하기
3. 처음 풀이
- [1,3], [2,6], [8, 10], [15, 18]이 있다.
- 우선 [1,3]의 좌우 값을 temp_left, temp_right에 저장한다.
- [1,3] 오른쪽 3과 다음 구간 [2,6]의 왼쪽 2를 비교하면 3이 더 크거나 같으므로 겹치는 것을 알 수 있다.
- 그러면 3과 6중 큰 6으로 temp_right를 업데이트한다.
- temp_right 6과 [8,10] 왼쪽 8을 비교하면 6이 작으므로 겹치지 않는 것을 알 수 있다.
- 그렇다면 temp_left, temp_right로 만들어진 병합 구간 [1, 6]을 result에 추가한다.
- 그 다음 [8,10]의 좌우 값을 temp_left, temp_right에 저장
- [8,10]의 오른쪽 10과 다음 구간 [15,18] 왼쪽 15를 비교하면 10이 더 작으므로 겹치지 않는다.
- 따라서 temp_left, temp_right로 만들어진 병합 구간 [8, 10]을 result에 추가
- 이때 발생하는 edge 케이스는 병합하다가 끝까지 가는 경우, 그리고 마지막 하나만 남은 경우이다. 이 경우는 따로 처리해주었고 edge 케이스를 따로 다루어준 것이 좀 깔끔하지 않은 느낌.
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort(key = lambda x: x[0])
if len(intervals) < 2:
return intervals
result = []
start, end = 0, 1
length = len(intervals)
left = intervals[start][1]
right = intervals[end][0]
while end < length:
temp_left = intervals[start][0]
temp_right = intervals[start][1]
while right <= temp_right:
temp_right = max(temp_right, intervals[end][1])
if end == length - 1:
result.append([temp_left, temp_right])
return result
else:
start += 1
end += 1
left = intervals[start][1]
right = intervals[end][0]
result.append([temp_left, temp_right])
start += 1
end += 1
if start == length - 1:
result.append([intervals[start][0], intervals[start][1]])
return result
else:
left = intervals[start][1]
right = intervals[end][0]
return result
4. 다른 풀이
- 비슷한 논리 구조, 코드가 간결함.
- 일단 오버랩 되지 않는 interval을 결과 merged에 추가해두고 나서 비교하기 때문에 나와 달리 edge case가 생기지 않는다.
- 결과물에 추가해두고 나서 수정을 하는 편이 완성시킨 후 추가하는 것보다 편할 수도 있다.
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort()
merged = []
for i in range(len(intervals)):
if merged == []:
merged.append(intervals[i])
else:
previous_end = merged[-1][1]
current_start = intervals[i][0]
current_end = intervals[i][1]
if previous_end >= current_start: # overlap
merged[-1][1] = max(previous_end,current_end)
else:
merged.append(intervals[i])
return merged
- unpacking을 이용하면 한층 더 간결하다.
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort(key=lambda pair:pair[0])
output = [intervals[0]]
for currstart,currend in intervals:
prevend = output[-1][1]
if prevend >= currstart:
output[-1][1] = max(prevend,currend)
else:
output.append([currstart,currend])
return output
5. 배운 점
- 결과물에 추가해두고 나서 수정을 하는 편이 완성시킨 후 추가하는 것보다 편할 수도 있다.
- sort, key, lambda를 이용한 정렬 문법 익혀두기
- intervals.sort(key=lambda x: x[0])
'Algorithm > LeetCode' 카테고리의 다른 글
LeetCode 59(Spiral Matrix II, Python) (1) | 2024.01.13 |
---|---|
LeetCode 57(Insert Interval, Python) (0) | 2024.01.12 |
LeetCode 55(Jump Game, Python) (0) | 2024.01.10 |
LeetCode 54(Spiral Matrix, Python) (0) | 2024.01.09 |
LeetCode 53(Maximum Subarray, Python) (1) | 2024.01.08 |