문제

문제

처음 작성한 코드

#5,7 Non Pass
def solution(n, lost, reserve):
    have = [1]*n # 체육복 가진 사람=1 아니면 0
    give = [0]*n # 빌려준 사람=1 아니면 0 -> 두 번 빌려줌을 방지하기 위해
    reserve = [i-1 for i in reserve] # index 헷갈려서 -1 함
    for i in lost:
        have[i-1] = 0 # lost면 체육복 안가졌으니 flag=0 
    for i in reserve: #여분 가진 사람
        if give[i]==0:
            if have[i]==0: have[i]=1
            elif i==n-1:
                if have[i-1]==0: have[i-1]=1
            elif i==0:
                if have[i+1]==0: have[i+1]=1
            else:
                if have[i-1]==0:have[i-1]=1
                elif have[i+1]==0: have[i+1]=1
            give[i]=1
    return have.count(1) 

 

코드 리뷰 후

def solution(n, lost, reserve):
    _lost = [i for i in lost if i not in reserve]
    _reserve = [i for i in reserve if i not in lost]
    for i in _reserve:
        if i-1 in _lost:
            _lost.remove(i-1)
        elif i+1 in _lost:
            _lost.remove(i+1)
    return n-len(_lost)

 

깨달은 점

너무 어렵게 생각했다.. -> 처음 작성한 코드 개판..

탐욕법이 도대체 뭔지 모르겠다..

테스트 케이스 5,7 번에서 NP 떠서 고민고민하고 있었는 데, 연주(내친구)가 반례를 찾아줬다..

제한사항중에 "여벌 체육복을 가져온 학생이 도난당할 수 있다." 라는 표현때문에 

reserve를 돌면서 i+1, i-1 에게 빌려주기전에 i인 자신에게 먼저 빌려주면 된다고 생각했는데 생각이 짧았다.

  -> 반례) solution(5, [3,4,5],[2,3,4]) 이렇게 되면 2가 3한테 먼저 빌려주게 되어버리니까 내가 생각한대로 구현하기 위해서는 for 문을 돌기전에 lost와 reserve에 공통적으로 있는 3,4 를 없애주고 시작하는 것이 맞다.

'Programmers' 카테고리의 다른 글

완주하지 못한 선수  (0) 2020.12.31
모의고사  (0) 2020.12.30
3진법 뒤집기  (0) 2020.12.29
2016년  (0) 2020.12.29
같은 숫자는 싫어  (0) 2020.12.29