Programming/코딩테스트
[코딩테스트 python] 프로그래머스 탐욕법(Greedy)
aram
2023. 4. 11. 22:32
그리디(Greedy)
- 단순하지만 강력한, 현재 당장 좋은 것만 선택하는 알고리즘
- 대부분의 문제는 그리디 알고리즘을 적용했을 때 '최적의 해'를 찾을 수 없을 가능성 높음 > 정당한지 검토 필수!
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
▲ 문제
def solution(n, lost, reserve):
student=[1 for _ in range(n)] #전체 학생수 만큼 list 생성
for lost_num in lost:
if lost_num in reserve: #도난당했지만 여벌이 있는 학생 제외
reserve.remove(lost_num)
else: #도난 당한 학생은 0으로 값 변경
student[lost_num-1] = 0
#앞의 학생부터 도난 당했는지 확인
#reserve가 정렬이 안 되어 있으면 예외상황이 생김
for r_num in sorted(reserve):
if r_num != 1 and student[r_num-2]==0:
student[r_num-2] = 1
elif r_num != n and student[r_num] == 0:
student[r_num] = 1
else:
pass
return sum(student)
직관적으로 알기 쉽게 학생 수만큼의 배열 생성
> 정렬이 되어 있으면 앞 순서부터 도난 여부 체크만 하면 ok
but, 이렇게 풀면 학생 수가 많을 경우 비효율적.
다른 사람의 풀이를 보면
전체 학생 수 - 도난학생 수로 깔끔하게 풀이👍
기존에 푼 코드에 응용하면 ?
def solution(n, lost, reserve):
# 여벌의 체육복을 가져온 학생이 1벌을 도난 당한 경우 제외
_reserve = [r for r in reserve if r not in lost]
_lost = [l for l in lost if l not in reserve]
#해당 여벌의 가져온 학생이 앞, 뒤 학생에게 빌려줄 수 있는 지 확인
for r in sorted(_reserve):
f = r - 1
b = r + 1
if r != 1 and f in _lost: #만약 1번학생이라면 앞번호가 없으니 제외
_lost.remove(f)
elif r != n and b in _lost: #만약 마지막 학생이라면 뒷번호가 없으니 제외
_lost.remove(b)
else:
pass
return n - len(_lost)
별도의 학생 리스트를 생성하지 않고
lost과 reserve를 비교해서 확인해서
빌려주면 lost에서 제거하는 식으로 학생 수 체크.
훨씬 간편!