2018년 9월 11일 화요일

firstDuplicate 문제

CodeFights라는 사이트의 이름이 Code Signal로 바뀐 것 같다.
여기에서 본 문제 중 firstDuplicate라는 문제가 있는데,
지금은 문제가 좀 바뀐 것 같지만, 내가 처음 봤을 당시 문제는 다음과 같다.

양의 정수 수열이 입력으로 들어오면, 그 수열에서 처음으로 중복되는 수를 찾아서 리턴하는 문제인데, 여기서 처음으로 중복되는 수는 두 번째로 나온 수 기준으로 가장 앞에 있는 수를 뜻한다.
2, 1, 3, 5, 3, 2 가 있으면 처음으로 중복되는 숫자는 2가 아니라 3이된다.
그리고 중복되는 숫자가 없으면 -1을 리턴해야 한다.

얼핏보면 쉬워 보이지만, 조건이 하나 더 있다. 바로 메모리를 추가적으로 사용하지 않고 풀어야 한다는 것이다... (지금 들어가보면 그 조건이 사라져 있지만 이 조건이 있어야 어렵고 생각해볼만한 문제가 된다.)

boolean 배열이라도 하나 더 있어야 어떤 수가 이미 이 전에 나왔는지 체크를 할텐데... 어떻게 추가적인 메모리를 사용하지 않고 풀라는 걸까?
생각하다가 도저히 모르겠어서 다른 사람들의 모범 solution을 봤다.

추가적인 메모리는 사용할 수 없어도 주어진 수열은 활용할 수 있는데, 이것을 어떻게 활용하냐면,
입력으로 들어오는 수열의 수가 양의 정수라는 점, 입력으로 들어오는 수의 크기는 1이상 수열의 길이 이하라는 점을 이용해서, 해당 수를 주어진 수열의 index(해당하는 수 - 1)로 하여 index에 해당하는 값을 음수로 만든다. 그래서 그 index에 있는 수가 음수이면 그 수는 이미 한 번 나왔던 수라는 것을 알 수 있다.
참고로 음수로 바꿔서 체크하므로, 어떤 수 x를 볼 때는 x의 절대값으로 봐야한다.

예전에 한 번 본 문제 같기도 한데... 아무튼 전혀 생각을 못했다. 비록 수열이 양의 정수로 구성되어 있을 때만 가능하긴 하지만 정말 멋진 풀이같다.


댓글 없음:

댓글 쓰기