Categories
xacdo

리트코드 푸는 법

코딩 시험이 한국은 백준(https://www.acmicpc.net/) 스타일이라면, 미국은 리트코드(https://leetcode.com/) 스타일이다. 그래서 페이스북의 경우에는 리트코드의 medium에서 hard 수준의 문제 2개를 30분 안에 풀어야 한다. 각 문제당 15분씩인 셈이다. 그러면 일단 문제를 읽고 이해하는데 2-3분, 명확하지 않은 부분을 질문하는데 1-2분, 내가 어떻게 풀지를 설명하는데 1-2분, 그래서 코딩하는데 5-7분, 코드를 하나씩 짚어가면서 테스트하는데 1-2분 정도가 걸린다. 여기서 중간에 인터뷰어가 개입하면 유연하게 받아서 고쳐가면서 풀어야 한다.

그 얘기는 코딩 시험인데 코딩의 비중이 생각보다 높지 않다는 얘기다. 한 문제당 15분 중에 순수하게 코딩에 쓰는 시간이 5분밖에 안 된다. 나머지는 계속 말을 하며 아이디어를 주고 받고 해야 한다. 이것은 두 가지를 의미하는데, 첫째로는 너무 코딩에만 집중하면 안되지만, 둘째로 코딩은 당연히 기본적으로 잘 해야 한다는 것이다.

내가 힘들었던 점은 일단 아이디어가 없다는 것이었다. 리트코드의 솔루션과 다른 사람들의 소스코드를 보면, 참 세상에 똑똑한 사람들이 많구나, 이렇게 참신한 아이디어가 많구나 감탄스러웠다. 나는 그런 아이디어를 떠올릴 수 없는데.

반짝이는 아이디어를 잘 떠올리는 사람이라면 이런 고민을 할 필요가 없을 것이다. 하지만 나같이 아이디어가 잘 안 나오는 사람이라면 방법은 문제를 많이 보는 수 밖에 없다. 많은 문제들을 보고 해답을 보고 익숙해져야 한다. 그래야 머리가 나빠도 적당히 풀 수 있을 것이다.

근데 아이디어가 있어도 코딩 실력이 없으면 완성이 안 된다. 아이디어를 구체적으로 끝까지 만들어내야 한다. 이것은 꽤 기계적인 과정인데, 여기서 내가 힘들었던 점은 타자를 빨리 쳐야 한다는 것이었다. 문제를 15분 안에 풀려면 생각보다 상당히 빨리 쳐야 한다. 썼다 지웠다 하면 안되고, 앞에서부터 순서대로 한 번에 에러 없이 쳐야 한다.

여기서 내가 한 일은 일단 키보드와 마우스를 아주 좋은 것으로 준비하고, 모니터를 눈 높이로 맞추고, 적절한 글자 크기와 밝기를 맞추고, 의자의 높이와 책상 배치를 잘 하는 것이었다. 이게 별 거 아닌 것 같아도 상당히 영향을 준다. 8분 걸릴 코딩을 7분으로 줄여준다. 인터뷰 시간은 매우 짧기 때문에 1분도 소중하다. 투자할 가치가 있다.

그 다음으로는 코드를 짧게 줄여야 한다. 10자 칠 걸 5자 치고, 5자 칠 걸 3자 치면 더 빨리 풀 수 있다. 같은 문제를 계속 고쳐가며 더 빨리 풀 수 있는 방법을 고민한다. 람다(lambda) 식도 쓰고, 삼항연산자(conditional expresssion)도 쓰고, early return도 쓰고, 변수나 펑션의 이름도 짧게 줄이고 해서 손에 익숙하게 한다. 물론 이런 걸 너무 짧게 줄이면 pythonic하게 되서 남들이 잘 못 알아보는 나만의 암호같이 되기도 하는데, 이런 경우에는 인터뷰어와의 소통을 위해서 적당히 알아볼 만큼 풀어 써야 한다.

그리고 한 문제를 여러 가지 방법으로 풀 수 있는 경우가 많고, 인터뷰에서도 의도적으로 그런 문제를 많이 내는데, 그 경우에는 일단 가장 짧고 쉬운 방법을 먼저 답해야 한다. 나머지 더 어려운 방법은 질문이 들어오면 바로 답하면 된다. 굳이 내가 먼저 치고 나갈 필요가 없다. 혹시라도 인터뷰어가 다른 방향으로 물어보고 싶은데 내 마음대로 내가 잘 하는 쪽으로 파고들면 실망할 것이다.

하여튼 코딩 시험은 짧은 시간 안에 내가 얼마나 빠릿빠릿한 사람인지를 보여줘야 하는 시험이다. 타자도 빨리 치고, 뭘 물어봐도 잘 대답하고 그러면 된다. 여기서 조금 더 나아가서 아이디어가 안 떠오를 때가 있는데, 이럴 때 임기응변으로 대응할 수 있다면 참 좋겠지만, 내가 그렇게까지 머리가 반짝이는 사람이 아니라면 나름의 비상 플랜을 세워놔야 한다.

내가 생각해놓은 방법은 평범하게 유형별로 자주 나올 수 있는 방법들을 나열하는 것이다. 예를 들어 배열이라면 Two pointer를 쓸까? Set 아니면 Map을 쓸까? 그것도 아니면 recursion, Stack을 써야 할까? 이렇게 이것 저것 얘기하다보면 인터뷰어가 Set과 Map을 쓰는 건 어떻게 다를까요? 이런 식으로 살짝 힌트를 준다. 그러면 인터뷰어에게 감사하며 그쪽 방향으로 생각을 발전시키면 된다.

아니면 아예 기계적으로 boilerplate 코드를 시키는 경우도 있다. 보통은 반복적이고 귀찮고 길어서 대충 어디서 라이브러리를 가져다 쓰는 건데, 아이디어가 없는 나같은 사람이라면 차라리 다행이기도 하다. 이건 그냥 문제에서 주는 조건을 있는 그대로 정확히 빠르게 코드로 옮기면 된다. 이런 문제에서 제일 중요한 건, 왼손 검지를 F키 위에, 오른손 검지를 J키 위에 놓고, 손가락을 정확히 키보드에 맞춘 다음에 오타가 나지 않도록 주의하면서 일필휘지로 코드를 써내려가는 것이다.

나는 이게 영 안되서 한 문제를 7번까지 반복해서 푼 적도 있고, 보통은 2-3번은 다시 풀어본다. 타이머를 켜고 시간을 재가며 손에 익을 때까지 반복한다.

그리고 나는 안되는 걸 붙들고 꾸역꾸역 시간을 보내는 걸 좋아하기 때문에, 타이머가 30분을 넘어가면 깨끗이 포기하고 정답을 보거나 남의 코드를 보기로 했다. 그래서 문제를 이해하고 다시 풀어보고, 손에 익을때까지 반복하고, 내 문장으로 간단히 설명해서 나중에 인터뷰 직전에 한 번에 훑어볼 수 있도록 정리해놓는다. 예전에 고승덕 변호사가 공부할 때, 시험 전 날 하루에 전부 복습할 수 있도록 정리한다고 했는데, 맞는 말이다. 짧게 정리해야 복습할 수 있다. 나는 개발자지만 코드보다 글이 더 익숙해서, 내가 쓴 내 스타일의 문장을 읽는 게 더 이해가 잘 되고 빠르다. 하지만 코드도 까먹을 수 있으니 옆에 같이 정리해놓는다.

그리고 보통 ICPC 등의 코딩 경시대회를 볼 때는 자주 쓰는 코드들을 미리 구현해놓고 가져다 쓰는데, 예를 들어 union-find, gcd 같은 것들은 자주 나오지만 기본 라이브러리에서 지원을 안 하니까 미리 generic하게 짜 놓고, 시험이 시작하자마자 일단 복사해서 붙여놓고 시작한다. 이걸 허용하지 않는다면 미리 외워서 빠르게 쳐 놓고 시작한다. 마찬가지로 자주 나오는 펑션들은 기계적으로 외우거나 책상 옆에 cheat sheet로 만들어 놓는 것도 좋다. 아니면 그냥 cheat sheet를 시험 직전에 보고 외워도 된다.

내가 추천하는 리트코드 코스는, 일단 유료 결제를 하고 (돈을 아끼면 안된다) Top interview questions로 잘 정리해놓은 것들 위주로 푸는 것이다. 그리고 하루에 비슷한 문제들을 모아서 푸는 게 좋다. 이거 풀었다 저거 풀었다 하면 생각이 전환되는데 시간이 걸려서 더 오래 걸린다. 애초에 인터뷰에서도 대체로 비슷한 문제끼리 모아서 물어본다. serialize 문제를 내면 deserialize 문제를 낸다던가 하는 식으로. 비슷한 문제들끼리 풀어야 생각도 정리가 되고 추상화도 된다.

By xacdo

Kyungwoo Hyun

Leave a Reply

Your email address will not be published.