[Python/javascript] 프로그래머스 : 체육복
https://school.programmers.co.kr/learn/courses/30/lessons/42862
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
체육복을 빌릴 때, 본인보다 한 번호 적은 학생에게 빌리는 것을 우선으로 한다고 가정하고 풀이했다
만일 reserve = [1,3] lost = [2,4]일 때 본인보다 1 큰 학생에게 빌리는 것을 우선한다면,
2번 학생은 3번에게, 4번 학생은 빌릴 수가 없게 되기 때문이다.
이상적인 형태는 2번 학생은 1번에게, 4번 학생은 2번에게 빌려 주는 것이기 때문에 본인보다 한 번호 작은 학생에게 빌리는 것을 우선한다고 생각하고 풀이를 했다.
추가적으로 고려할 것은, 여분을 잃을 것을 먼저 고려해야한다고 생각했다.
그래서 나는 여분 잃을 것을 먼저 고려(reserve와 lost 간) 후 왼쪽 학생에게 빌리는 로직을 설계했다.
Python
def solution(n, lost, reserve):
answer = 0
students = [False] * n
for idx in range(len(reserve)):
if reserve[idx] in lost: # 여분이 있는 학생이 체육복을 잃은 경우
reserve.pop(idx)
lost.remove(reserve[idx])
students[idx - 1] = True
for idx in range(1,n+1):
if idx in lost: # 체육복 잃어버린 경우
if idx - 1 in reserve:
students[idx - 1] = True
reserve.remove(idx - 1)
continue
elif idx + 1 in reserve:
students[idx - 1] = True
reserve.remove(idx + 1)
continue
else: # 체육복 안 잃어버린 경우
students[idx - 1] = True
for res in students:
if res == True:
answer+= 1
return answer
기존 풀이,,, 그러나 런타임 에러가 떴고, for loop 안에서 pop/remove를 하면 안 된다고 판단하여 다른 로직을 생각해야만 했다.
어떻게 remove랑 pop을 문제 없이 할 수 있을까? 내가 결국 해야하는 것은, pop과 remove가 아니라, lost와 reserve에 둘 다 들어있는 경우의 수를 한번 걸러주는 것이다.
def solution(n, lost, reserve):
answer = 0
students = [1] * n
lost_set = list(set(lost) - set(reserve)) # 진짜로 잃어버린 경우만 남도록
reserve_set = list(set(reserve) - set(lost)) # 진짜로 여분이 있는 경우만 남도록
for idx in lost_set:
students[idx - 1] -= 1
for idx in reserve_set:
students[idx - 1] += 1
for idx in range(n):
if students[idx] == 0:
if n > 0 and students[idx - 1] >= 2: # 0번이 아니고, 왼쪽의 학생이 체육복을 2개 이상 가진 경우
students[idx] += 1
students[idx - 1] -= 1
elif students[idx + 1] >= 2: # 그렇지 않으면 오른쪽만 봐주면 된다
students[idx] += 1
students[idx + 1] -= 1
for cloth in students:
if cloth:
answer += 1
return answer
set를 사용하면 pop, append 연산을 사용하지 않아도 될 것이라고 판단했다.
set를 사용하지 않고 새 배열을 만들거나 해도 될 것 같았으나 연산 시간의 문제로 append를 최대한 줄이고 싶었다. 그래서 set을 사용해 풀었다.
하지만 여전히 런타임 에러가 있었고,, 이를 극복하기 위해
Python Answer
def solution(n, lost, reserve):
answer = 0
students = [1] * n
lost_set = list(set(lost) - set(reserve)) # 진짜로 잃어버린 경우만 남도록
reserve_set = list(set(reserve) - set(lost)) # 진짜로 여분이 있는 경우만 남도록
for idx in lost_set:
students[idx - 1] -= 1
for idx in reserve_set:
students[idx - 1] += 1
for idx in range(n):
if students[idx] == 0:
if idx > 0 and students[idx - 1] >= 2:
students[idx] += 1
students[idx - 1] -= 1
elif idx < n - 1 and students[idx + 1] >= 2:
students[idx] += 1
students[idx + 1] -= 1
for cloth in students:
if cloth:
answer += 1
return answer
코드로 수정해주었다. 인덱스가 0이 아닌 경우 처리가 단순히 안 되었던 것.
Javascript Answer
function solution(n, initLost, initReserve) {
var answer = 0;
const lostSet = new Set(initLost);
const reserveSet = new Set(initReserve);
const lost = Array.from(new Set([...lostSet].filter(x => !reserveSet.has(x))));
const reserve = Array.from(new Set([...reserveSet].filter(x => !lostSet.has(x))));
let students = Array(n).fill(1)
// 왼쪽에서부터 점검해주면 된다.
for (idx = 0; idx < lost.length; idx++) {
students[lost[idx] - 1] -= 1
}
for (idx = 0; idx < reserve.length; idx ++) {
students[reserve[idx] - 1] += 1
}
for (idx = 0; idx < n; idx++) {
if (students[idx] == 0) {
if (idx > 0 && students[idx - 1] >= 2) {
students[idx] += 1
students[idx - 1] -= 1
} else if (idx < n - 1 && students[idx + 1] >= 2) {
students[idx] += 1
students[idx + 1] -= 1
}
}
}
for (idx = 0; idx < n; idx++) {
if (students[idx]) {
answer += 1
}
}
return answer;
}'알고리즘 > programmers' 카테고리의 다른 글
| [Python/Javascript] 프로그래머스 2020 카카오 인턴십 : 키패드 누르기 (0) | 2024.01.09 |
|---|---|
| [Python/Javascript] 프로그래머스 2022 KAKAO TECH INTERNSHIP 성격 유형 검사하기 (1) | 2024.01.09 |
| [Python/Javascript] 프로그래머스 : 2019 KAKAO BLIND RECRUITMENT 실패율 (0) | 2024.01.04 |
| [Javascript] 프로그래머스 : [1차] 비밀지도 (0) | 2023.12.28 |
| [Javascript] 프로그래머스 : 숫자 문자열과 영단어 (0) | 2023.12.28 |
