2024년 3월 3일 일요일

leetcode.com 1851. Minimum Interval to Include Each Query

문제 링크: https://leetcode.com/problems/minimum-interval-to-include-each-query/description/

파이썬 소스: https://bit.ly/3wDBYny
from typing import List
import heapq

class Solution:
    def minInterval(self, intervals: List[List[int]], queries: List[int]) -> List[int]:
        length = len(intervals)
        intervals.sort()
        heap = []
        dict = {}
        idx = 0

        for q in sorted(queries):
            while idx < length and intervals[idx][0] <= q:
                left, right = intervals[idx]
                l = right - left + 1
                heapq.heappush(heap, [l, right])
                idx += 1

            while heap and heap[0][1] < q:
                heapq.heappop(heap)

            dict[q] = heap[0][0] if heap else -1

        return [dict[q] for q in queries]

leetcode.com 435. Non-overlapping Intervals

문제 링크: https://leetcode.com/problems/non-overlapping-intervals/description/

파이썬 소스: https://bit.ly/49UJxED
from typing import List

class Solution:
    def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
        intervals.sort(key=lambda x: x[1])

        count_total = len(intervals)
        count_non_overlapped = 1
        prev = 0

        for idx in range(1, count_total):
            # prev의 end가 idx의 start 보다 작거나 같으면
            # 이 둘은 overlapped 되는 부분이 없다는 의미
            if intervals[prev][1] <= intervals[idx][0]:
                prev = idx
                count_non_overlapped += 1

        return count_total - count_non_overlapped

leetcode.com 56. Merge Intervals

문제 링크: https://leetcode.com/problems/merge-intervals/description/

파이썬 소스: https://bit.ly/4bXKm1i
from typing import List

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        intervals.sort(key = lambda x: x[0])
        answer = [intervals.pop(0)]

        while len(intervals) > 0:
            a_start, a_end = answer.pop()
            b_start, b_end = intervals.pop(0)
            over_lapped: bool = False

            if (a_start <= b_start and b_end <= a_end)  \
                or (a_start <= b_start <= a_end)    \
                or (a_start <= b_end <= a_end):
                over_lapped = True

            if over_lapped:
                start = min(a_start, b_start)
                end = max(a_end, b_end)
                answer.append([start, end])
            else:
                answer.append([a_start, a_end])
                answer.append([b_start, b_end])

        return answer

2024년 3월 1일 금요일

leetcode.com 57. Insert Interval

문제 링크: https://leetcode.com/problems/insert-interval/description/

파이썬 소스: https://bit.ly/48weoXb
from typing import List

class Solution:
    def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
        intervals.append(newInterval)
        intervals.sort(key=lambda x: x[0])

        answer = [intervals.pop(0)]
        while len(intervals) > 0:
            a_start, a_end = answer.pop()
            b_start, b_end = intervals.pop(0)
            over_lapped = False

            if a_start <= b_start and b_end <= a_end:
                over_lapped = True
            elif b_start <= a_start and a_end <= b_end:
                over_lapped = True
            elif a_start <= b_start <= a_end:
                over_lapped = True
            elif a_start <= b_end <= a_end:
                over_lapped = True

            if over_lapped:
                start = min(a_start, b_start)
                end = max(a_end, b_end)
                answer.append([start, end])
            else:
                answer.append([a_start, a_end])
                answer.append([b_start, b_end])

        return answer

programmers.co.kr 코딩테스트 연습 힙(Heap) 디스크 컨트롤러

programmers.co.kr 코딩테스트 연습 힙(Heap) 디스크 컨트롤러
파이썬 소스: https://bit.ly/4bNyGhw

이 문제에서는 전체 요청을 처리 해야 하지만, 그와 동시에, 최소시간안에 처리해야 하는 문제입니다.

따라서, 짧은 요청을 먼저 실행해야, 아직 실행되지 않은 요청들이 대기하는 시간이 줄어들게 되서,

최소시간안에 처리하게 되는 것입니다.


a 0ms, 3ms

b 0ms, 2ms

c 0ms, 1ms


이렇게 3개의 요청을 받았다고 하면 (여기서 부터는, 요청을 job으로 작성하겠습니다.)

3개의 요청은 모두 0ms 에 시작할 수 있습니다. (job의 시작시간을 start_time으로 작성하겠습니다.)

start_time이 모두 0ms 로 같기 때문에 3개 job 모두 처음부터 실행할 수 있습니다.

그러면 a, b,c 3가지 중에 어떤 것을 먼저 실행할 지 선택해야 합니다.


a를 선택했다고 가정하면, a 는 3ms 동안 실행합니다.

b 와 c 는 a를 실행하는 3ms 동안 b와 c 모두 3ms 동안 대기 해야 합니다.


하지만, c 를 선택했다면, a 와 b는 c의 실행시간(duration으로 작성하겠습니다) 1ms 동안만

기다리게 됩니다. 따라서, c를 선택해야 합니다.


즉, 가장 먼저 실행해야하는 job은 start_time이 가작 작은 job이고, start_time 가장 작은

job이 여러개가 있다면, 그중에서는 duration이 가장 작은 job을 선택해야,

전체 job의 대기시간을 가장 작게 할 수 있습니다.


여기까지 문제를 풀고 파이썬 코드를 작성해보면 아래와 같습니다.

 

def my_sort(a, b):
	if a[0] < b[0]:
		return -1
	elif a[0] > b[0]:
		return 1
	else: # a[0] == b[0]
		if a[1] < b[1]:
			return -1
		elif a[1] > b[1]:
			return 1
		else: # a[1] == b[1]
			return 0

def solution(jobs: List):
	current_time = 0  # 현재 시간
	count = len(jobs) # job의 개수
	answer = 0    	# 전체 걸린 시간
	jobs = sorted(jobs, key=cmp_to_key(my_sort))
	# my_sort를 사용해서 정렬하구요, jobs 를 start_time이 작은 순서로 정렬하고,
	# start_time이 같은 job은 duration이 작은 순서로 정렬 합니다.

 

job은 start_time이 정해저 있기 때문에, 현재 시간을 가리키는

current_time 변수가 필요합니다. start_time <= current_time 인 job 만 실행할 준비가 된 것입니다.

 

def my_sort(a, b):
	if a[0] < b[0]:
    	return -1
	elif a[0] > b[0]:
    	return 1
	else: # a[0] == b[0]
    	if a[1] < b[1]:
        	return -1
    	elif a[1] > b[1]:
        	return 1
    	else: # a[1] == b[1]
        	return 0

def solution(jobs: List):
	current_time = 0  # 현재 시간
	count = len(jobs) # job의 개수
	answer = 0    	# 전체 걸린 시간
	jobs = sorted(jobs, key=cmp_to_key(my_sort))
	# my_sort를 사용해서 정렬하구요, jobs 를 start_time이 작은 순서로 정렬하고,
	# start_time이 같은 job은 duration이 작은 순서로 정렬 합니다.

	while len(jobs) > 0:
		is_idle: bool = True

		while len(jobs) > 0 and jobs[0][0] <= current_time:
			is_idle = False
			[start_time, duration] = jobs.pop(0)

		if is_idle:
			current_time += 1

	return int(answer / count)

 

is_idle 변수는 current_time에서 아무 job도 실행되지 않았다면, current_time을 1 증가

시켜주는 역할 을 합니다.


실행할 준비가 된 job들을 jobs 에서 하나씩 꺼내올 수 있게 되었습니다. 하지만 꺼내온

job들도 duration 짧은 job 부터 실행해야 하는데요, 여기서 heap 자료구조를

사용해서, duration이 짧은 순서로 job를 정렬합니다.

 

def my_sort(a, b):
	if a[0] < b[0]:
    	return -1
	elif a[0] > b[0]:
    	return 1
	else: # a[0] == b[0]
    	if a[1] < b[1]:
        	return -1
    	elif a[1] > b[1]:
        	return 1
    	else: # a[1] == b[1]
        	return 0

def solution(jobs: List):
	current_time = 0  # 현재 시간
	count = len(jobs) # job의 개수
	answer = 0    	# 전체 걸린 시간
	jobs = sorted(jobs, key=cmp_to_key(my_sort))
	# my_sort를 사용해서 정렬하구요, jobs 를 start_time이 작은 순서로 정렬하고,
	# start_time이 같은 job은 duration이 작은 순서로 정렬 합니다.
	heap = []

	while len(jobs) > 0 or len(heap) > 0:
		is_idle: bool = True

		while len(jobs) > 0 and jobs[0][0] <= current_time:
			is_idle = False
			[start_time, duration] = jobs.pop(0)
			heapq.heappush(heap, [duration, start_time])

		if len(heap) > 0:
			is_idle = False
			[duration, start_time] = heapq.heappop(heap)

			answer += (current_time - start_time)
			answer += duration
			current_time += duration

		if is_idle:
			current_time += 1

return int(answer / count)

start_time <= current_time 인 job을 꺼내서, heap 에 duration과 start_time을 함께

넣어주게되면, heapq.heappop()에서 duration이 짧은 job 부터 리턴 해 줍니다.


현재시간은 current_time 에서 start_time을 빼주면, 이 job 이 기다린 시간을

계산해서, answer에 더해주고, 이 job의 duration도 함께 answer에 더해 줍니다.


마지막으로 answer / count 를 한 뒤에, 소수 점을 제외하기 위해서 int() 를 사용합니다.

2024년 2월 18일 일요일

215. Kth Largest Element in an Array

문제 링크: https://leetcode.com/problems/kth-largest-element-in-an-array/description/

파이썬 소스: https://bit.ly/3w4bI5j

 계속 heapq를 사용해서 풀 수 있는 문제가 나오네요.

k개수 만큼 큰 수를 heap에 저장하구요, heappush() heappushpop()에서 작은 숫자는 heap에서

빠지게 됩니다. heapq를 사용하면 쉽게 풀 수 있는 문제입니다.


from typing import List
import heapq

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        heap = []

        for num in nums:
            if len(heap) == k:
                heapq.heappushpop(heap, num)
            else:
                heapq.heappush(heap, num)

        return heap[0]


2024년 2월 4일 일요일

leetcode.com 973. K Closest Points to Origin

문제 링크: https://leetcode.com/problems/k-closest-points-to-origin/description/

파이썬 소스: https://bit.ly/49icv0X


이번 문제도 heapq를 사용해서 풀 수 있습니다.



from typing import List
import heapq

class Solution:
    def kClosest(self, points: List[List[int]], k: int) -> List[List[int]]:
        heap = []

        for x, y in points:
            distance = x*x + y*y

            if len(heap) == k:
                heapq.heappushpop(heap, (-distance, x, y))
            else:
                heapq.heappush(heap, (-distance, x, y))

        return [[x, y] for dist, x, y in heap]