- 알고리즘 블로그 운영중
- 프로그래밍 대회 다수 수상
- ICPC Seoul Regional 3회 진출 (2021, 2022, 2023)
- 2024 ICPC Asia Pacific Championship 진출
강의
수강평
- 세계 대회 진출자가 알려주는 코딩테스트 A to Z (with Python)
- 세계 대회 진출자가 알려주는 코딩테스트 A to Z (with Python)
- 세계 대회 진출자가 알려주는 코딩테스트 A to Z (with Python)
- 세계 대회 진출자가 알려주는 코딩테스트 A to Z (with Python)
- 세계 대회 진출자가 알려주는 코딩테스트 A to Z (with Python)
게시글
질문&답변
BOJ 1342 메모리초과 관련
안녕하세요, gjwns2044님!메모리 초과가 나는 이유는 이 질문글(링크)을 참고해주시면 좋을 것 같습니다. 크기가 n인 리스트에 대해, permutations를 사용해도 어차피 n!만큼의 원소들을 담고 있는 객체를 생성하므로 메모리적인 측면에서 set으로 둘러싼 것과 큰 차이가 없지 않나요?이에 대한 답은 no입니다. 파이썬의 permutations 함수는 모든 순열을 한꺼번에 저장하지 않고, 필요할 때마다 하나씩 생성하는 제너레이터(generator)입니다.재너레이너(generator)란 한 번에 모든 데이터를 메모리에 저장하지 않고, 필요할 때마다 값을 생성해서 반환하는 함수 또는 객체입니다. 따라서, 이러한 방식을 이용하면 메모리를 효율적으로 사용할 수 있습니다.아래와 같은 형식으로 permutations 객체를 생성하면, next 함수를 통해서 다음의 원소를 접근하여 메모리 효율적으로 모든 순열의 원소를 살펴볼 수 있는 것입니다. (이러한 permuations를 for문에 이용해도 이와 같이 메모리 효율적으로 돌아가게 됩니다.)from itertools import permutations data = [1, 2, 3] perm_gen = permutations(data, 2) # 제너레이터 객체 생성 print(next(perm_gen)) # (1, 2) → 첫 번째 순열을 생성 print(next(perm_gen)) # (1, 3) → 두 번째 순열을 생성 print(next(perm_gen)) # (2, 1) → 세 번째 순열을 생성이러한 방식을 lazy evaluation(지연 평가)라고 하므로 참고하시면 좋을 것 같습니다. 질문에 대해 만족스러운 답변이 되었기를 바랍니다!추가로 궁금하신 점이나 더 자세한 설명이 필요하시다면 언제든지 말씀해 주세요. 😄
- 0
- 2
- 39
질문&답변
진짜 엄청나네요. 이 가격에 새로운 컨텐츠 추가라니
안녕하세요, rhkdtjd_12님!좋게 봐주셔서 정말 감사합니다! 코딩테스트 A to Z라는 제목에 걸맞게, 처음부터 끝까지 체계적으로 학습할 수 있도록 강의를 만들기 위해 노력하고 있습니다. 계속 반복해서 공부하시면서 궁금한 점이 생기면 언제든 편하게 질문 남겨주세요. 앞으로도 더 좋은 강의가 될 수 있도록 꾸준히 업데이트해 나가겠습니다. 열심히 공부하셔서 원하는 목표 꼭 이루시길 응원하겠습니다! 화이팅! 💪🔥
- 0
- 1
- 111
질문&답변
섹션3 브루트포스 알고리즘 1342 풀이1 질문
안녕하세요, kimgguggury1002님!인접한 문자가 같은 지 아닌 지를 구하는 부분은 아래의 코드입니다.for perm in permutations(S): ok = True for i in range(0, len(S) - 1): if perm[i] == perm[i + 1]: ok = False break ans += ok 위의 과정을 거치면 ans는 중복된 문자열을 고려하지 않고 문제의 조건을 만족하는 문자열의 개수가 담겨 있습니다. 중복된 문자열을 고려하지 않고 경우의 수를 구했으니 중복된 문자열을 고려해야 하며, 이를 처리하는 부분이 질문자님께서 올려주신 코드 부분입니다. 중복된 문자열을 고려하여 처리하는 방법은 같은 것이 있는 순열의 개념을 이용하면 되며, 이러한 내용은 해당 강의의 2:10 - 4:02 부분에서 설명하고 있으니 참고하시면 될 것 같습니다! 질문에 대해 만족스러운 답변이 되었기를 바랍니다!추가로 궁금하신 점이나 더 자세한 설명이 필요하시다면 언제든지 말씀해 주세요. 😄
- 0
- 2
- 61
질문&답변
boj 3020
안녕하세요, tocc22님! AttributeError 런타임에러가 나는 이유input은 함수이므로, 재설정할 때 input = lambda: sys.stdin.readline().rstrip() 와 같이 작성해주셔야 합니다. 이를 바꾸면 런타임 에러는 해결이 될 것입니다. 이렇게 풀면 메모리나 시간초과가 날까요?코드를 자세히 살펴 보았는데요, 해당 코드는 정확도 측면에서는 맞는 풀이라고 생각이 듭니다. 하지만, 효율성이나 메모리 측면에서는 좀 문제가 있어 보입니다. 이에 대해 제가 바로 설명을 해드릴 수도 있으나, 한 번 tocc22님이 풀이 코드에 대해 시간 복잡도와 사용하는 메모리를 계산해 보시는 것을 추천드립니다! 시간 복잡도와 사용하는 메모리 계산을 해서 나온 결과와 과정을 답글로 작성해 주시면, 제가 더 자세하게 답변을 드리겠습니다! 물고기를 잡아주는 것이 아닌 잡는 법을 알려드리는 과정이라고 좋게 생각해주시면 감사하겠습니다 :)
- 0
- 1
- 60
질문&답변
제가 공부하는 방법이 괜찮은지 궁금합니다
안녕하세요, 말랑말랑한 캥거루님! Q1. 원래 자바로 공부하다가 파이썬이 코테에 유리하다는 것을 느끼고 바꿨더니 문법 문제가 생김A) 파이썬 문법 같은 경우는 강의와 강의 자료 중간중간에 문법 팁이나 원리에 대해 설명하고 있습니다. 그럼에도, 모르는 부분이 자주 나온다면 간단한 파이썬 문법 강의(링크) 등을 듣고 강의를 수강하면 도움이 될 것 같습니다. 추가로, GPT를 이용하여 그때그때 모르는 부분을 빠르게 찾는 것도 도움이 될 것 같습니다. Q2. 문제를 풀 때 그때그때 문법 검색해 보고 블로그에 정리하는 식으로 공부할지 or 그냥 파이썬 문법 강의까지만 듣고 올지A) Q1과 비슷한 맥락으로, 문법은 기본적인 강의(링크) 등을 듣고 강의를 들으시면 도움이 될 것 같습니다. 추가로, 문법을 블로그나 개인 공간에 정리한다면 사용법 정도만 매우 간단하게 정리하는 것을 추천드립니다. 문법은 암기하는 것보다는 까먹었을 때마다 찾아보며 자연스럽게 익숙해지는 것이 좋기 때문입니다. 사실, 아예 정리를 하지 않고, 문법이나 사용법을 까먹었을 때마다 GPT에게 물어보며 반복하여 상기하는 정도만 해도 괜찮다고 생각이 듭니다. Q3. 실버 문제가 아직 설계부터 어렵고, 수학 문제가 나오면 어버버거리는데, 이걸 문제를 다 못 풀어 봤어도 혼자 30분 정도 접근해 보고, gpt에 물어봐서 나의 문제점을 이해하고 문제 풀이 강의를 듣는 식으로 해도 되는 건지?A) 만약, 문제를 풀 때 못 푼 이유가 몰랐던 개념이나 테크닉 때문인 경우가 잦다면, 이는 관련된 개념이나 테크닉 등 경험이 부족하여 그럴 확률이 높습니다. 즉, 정답과 해설을 보며 개념과 테크닉 등을 빠르게 습득하여 경험치를 늘리는 것이 도움이 됩니다. 따라서, 문제를 고민하는 시간은 최대 30분 정도로 잡고 문제의 정답 풀이(또는 해설 강의)를 보며 경험치를 빠르게 늘리며 공부하는 것이 효율적일 것입니다.만약, 못 푼 문제의 해설을 봤는데 알았던 알고리즘이라면, 이는 문제해결능력(문제를 올바르게 접근하는 능력)이 부족하여 그럴 확률이 높습니다. 따라서, 이러한 경우는 문제를 깊게 고민해 보며 문제해결능력을 늘리는 것이 도움이 되므로 최대 1시간 정도 고민하면 여러 접근을 해보는 좋을 것 같습니다.사실, 문제를 고민하는 시간 자체도 중요하지만, 밀도 있게 고민하는 것이 더욱 중요합니다. 즉, 10분을 고민하더라도 문제를 어떻게 풀 수 있을지, 시간 복잡도를 줄일 방법은 없는지, 내 풀이 논리에 오류는 없는지, 해당 문제가 어떤 알고리즘으로 풀리는 구조인지 등을 다각적으로 생각하며 풀어야 합니다.알고리즘 문제를 잘 푸는 사람들은 단번에 정답을 떠올리는 것이 아니라, 짧은 시간 안에 다양한 사고 과정을 거쳐 최적의 풀이를 도출합니다. 따라서, 위와 같은 사고 과정을 반복적으로 훈련하는 것이 중요합니다. 본 강의의 해설 강의에서는 문제 접근부터 다양한 풀이를 떠올리는 과정을 잘 다루고 있으니, 위와 같이 다각적으로 접근한 후에 해설 강의를 보며 나의 사고 과정을 계속 고쳐 나가면 좋을 것 같습니다. 추가적으로, GPT를 사용하여 여러 질문을 하며 문제점을 파악하는 것은 좋은 것 같습니다. 저 또한 공부를 할 때 제가 이해한 것이 맞는지 GPT를 통해 물어보고, 반론해 가며 공부하고 있으니, 이와 같이 활용하면 공부를 할 때 더 깊은 이해를 가져갈 수 있을 것 같습니다. 수학 문제가 나올 때 어려운 이유가, 몰랐던 수학 개념이 나와서 그러는지, 아니면 수학적인 사고력이 부족한 것인지를 파악할 필요가 있습니다. 만약, 몰랐던 수학 개념이 나와서 그렇다면, 수학적인 개념을 공부할 필요가 있으며, 본 강의의 코딩테스트에 필요한 수학 총정리에 나오는 내용을 충분히 공부하는 것을 추천드립니다. 만약, 수학적인 개념은 알고 있으나 사고력이 부족해서 못 풀었다면, 문제해결능력을 늘리면 자연스럽게 해결될 문제라고 생각합니다. 문제해결능력을 늘리는 방법은 위에서 설명한 것처럼 밀도 있게 고민하는 시간을 가지며 공부하면 자연스럽게 늘 거라고 생각합니다. Q4. 브론즈 같은 경우엔 일단 풀이가 깔끔하지 않더라도, 문제가 풀려서 풀고 강의를 들으면 됐었는데, 실버 문제로 오니까 아예 설계부터 못하는 것 같아서 공부를 어떻게 해야 하는 건지 모르겠음A) 어떻게 공부해야 할지는 Q3에 대한 답변에서 다룬 거 같으니, 해당 내용을 참고해 주시면 감사하겠습니다! 추가로, 문제를 풀 때 어떻게 접근해야 하는지는 섹션7의 문제를 푸는 사고과정 ('실전문제 풀이 파트2' 소개) 강의에 자세히 나와 있으니 참고하면 좋을 것 같습니다. (해당 강의는 앞 강의의 내용들이 선행되었다는 가정하에 제작한 영상이어서 모르는 개념이나 내용이 나올 수 있으니, 흐름 정도만 참고하면 좋을 것 같습니다.) 추가로, 강의는 한 번만 듣지 말고 2, 3회독 하는 것을 추천드립니다! 질문에 대해 만족스러운 답변이 되었기를 바랍니다!추가로 궁금하신 점이나 더 자세한 설명이 필요하시다면 언제든지 말씀해 주세요. 😄5점 수강평을 남겨주시면 향후 더 나은 강의를 만드는 데 큰 도움이 됩니다. 🌟
- 1
- 2
- 118
질문&답변
강의 내용 중 백트래킹 존재 여부
안녕하세요, hsk7953님!백트레킹 알고리즘 또한 강의에 포함되어 있습니다. 백트레킹은 브루트포스 알고리즘 부분에서 포함되어 있으며, 구체적으로는 브루트 포스 알고리즘 [문제풀이] : BOJ 1342, BOJ 2580 등에서 백트레킹 관련하여 다루고 있습니다. 백트레킹은 브루트 포스 알고리즘과 연계해서 학습하면 좋은 알고리즘이라 따로 분리하지 않고 이와 같이 제작하였습니다. ㅎㅎ 또 궁금하신 점 있으시면 문의해주세요 :)
- 0
- 1
- 71
질문&답변
DP 11053관련 질문있습니다.
안녕하세요, tocc22님!부분수열의 정의에 대해 혼동을 하여 발생한 문제 같습니다.부분수열은 기존 수열에서 원래 순서를 유지한 채 일부 원소를 골라내어 만든 새로운 수열을 의미합니다.따라서, 입력으로 주어진 수열에 대해 순서를 바꾸면 안됩니다! 질문해주신 코드에 대해 반례 테스트 케이스를 첨부하였으니 참고하시면 좋을 거 같습니다! [1번째 코드의 반례 테스트 케이스]7 10 20 10 30 20 50 40답은 4이며, 길이가 4인 부분 수열의 후보는 {10, 20, 30, 40} 또는 {10, 20, 30, 50} 이 있습니다. [2번째 코드의 반례 테스트 케이스]8 1 2 1 2 1 2 1 2답은 2이며, 길이가 2인 부분 수열의 후보는 {1, 2} 가 있습니다. 질문에 대해 만족스러운 답변이 되었기를 바랍니다!추가로 궁금하신 점이나 더 자세한 설명이 필요하시다면 언제든지 말씀해 주세요. 😄
- 0
- 1
- 61
질문&답변
17609 투포인터 문제를 재귀로 풀 경우가 궁금합니다!
안녕하세요, jinii915님!전체적으로 코드를 잘 짜주셨는데요.해당 문제는 브루트포스적으로는 못 풀고, 효율적인 풀이를 찾아야 하기 때문에 그리디한 사고를 더해서 O(N) 풀이로 해결해야 했는데요.강의에서는 그리디한 사고를 더한 풀이라고 했지만, 질문자님께서 말하셨듯이 백트레킹 풀이라고 생각하셔도 됩니다.(명칭은 중요하지 않습니다) 어쨌든 중요한 것은 강의에서의 정답 풀이 아이디어와 질문자님이 생각해 내신 아이디어가 똑같으며 시간 복잡도를 만족하는 풀이라는 것입니다! 따라서, 문제 접근을 아주 잘하신 것 같습니다! 결론부터 말씀드리면, 아주 잘하셨고 실제 코딩테스트에 나온 문제라면 통과하셨을 것입니다. 단지, 백준에서 통과하지 못한 이유는 해당 문제는 파이썬이 느림을 배려해 주지 않은 문제인 것으로 보입니다. 즉, 질문자님께서 구현하신 코드가 강의에 나온 코드보다 구현 효율성이 좀 떨어진 것으로 보입니다. 그러한 이유로 질문자님 코드에서 살짝 더 효율적으로 바꾼 아래의 코드는 아슬아슬하게 통과하였습니다.(입력을 arr에 받지 않고 바로 처리하였으며, 재귀 함수의 else 부분이 살짝 다릅니다.)import sys sys.setrecursionlimit(10**6) # 재귀 깊이 제한 늘리기 def recursion(value, left, right, count): # base if count > 1: return 2 if left > right: return count # recursive if value[left] == value[right]: return recursion(value, left+1, right-1, count) else: # 1. right를 옮겨보기 skip_right = recursion(value, left, right-1, count+1) # 2. left를 옮겨보기 skip_left = recursion(value, left+1, right, count+1) return min(skip_left, skip_right) T = int(input()) # 문자열 개수 for _ in range(T): value = input() left = 0 right = len(value)-1 print(recursion(value, left, right, 0))(사진)해당 문제의 시간 제한이 1초인데, 딱 1초로 아슬아슬하게 통과하는 모습이다... 이번 문제는 (파이썬을 배려해 주지 않은 문제여서) 운이 없었던 것으로 보이므로, 이번 문제가 시간 초과(또는 메모리 초과)를 나는 이유에 대해 깊게 생각하시지 않고 넘어가셔도 무방할 것 같습니다.그래도, 질문자님이 작성해주신 질문이나 코드를 보며 제가 알려드리면 좋을 것 같은 내용은 아래에 작성하오니 참고해 주시면 될 것 같습니다! [질문자님의 코드를 메모리 초과가 아닌 시간 초과로 봐야 하는 이유]질문자님의 제출 기록을 보니 PyPy3로 제출했을 때 메모리 초과가 났기 때문에, 질문에서 메모리 초과라고 언급해 주신 것 같은데요. 사실, 이는 시간 초과로 보는 것이 타당합니다. 왜냐하면, Python3로 제출했을 때는 시간 초과가 떴기(PyPy3로 제출했을 때만 메모리 초과가 떴기) 때문이죠.사실 PyPy3로 컴파일하면 Python3로 컴파일했을 때보다 빠른 이유는 메모리를 더 많이 사용해서 속도를 올리는 전략을 사용하기 때문입니다. 따라서, 질문자님의 코드도 "Python3로 제출했을 때 메모리초과가 나지 않았지만, PyPy3로 제출했을 때는 메모리를 더 사용하여 속도를 올리려다 보니 메모리 초과가 났다"라고 생각하시면 될 것 같습니다. [강의의 정답 코드가 질문자님 코드보다 효율적인 이유]강의에서 정답 코드와 질문자님의 코드 차이점은 회문인지를 검사하는 함수를 for문으로 구현하였느냐, 재귀함수로 구현하였느냐인데요. 회문을 검사하는 함수를 작성할 때는 for문으로도 구현 가능하며, 재귀함수로도 구현 가능합니다. 똑같은 로직을 for문과 재귀함수 중에서 어떤 것으로 구현하는 게 더 빠를까요? 당연히, for문이 빠릅니다. 그러한 이유는 재귀함수를 호출할 때는 for문에 비해 추가적으로 잡다한 작업(스택 메모리에 여러 정보들을 저장하는 작업)이 걸리기 때문이라고 생각해주시면 될 것 같습니다.따라서, 앞으로는 for문으로 구현 가능한 로직이면 재귀 함수보단 for문을 이용하여 구현하는 것을 추천드립니다! 사실, 질문자님의 코드도 C++로 작성하였다면 무난하게 통과할 것이기 때문에, 사실 코딩테스트에 이런 문제가 나왔다면 해당 코드로도 통과를 하였을 것입니다. 따라서, 이번 문제를 틀린 이유는 코드를 효율적으로 작성하지 않아서 보단 백준에서 파이썬 제출에 대한 배려를 해주지 않아서 가 더 적합한 이유라고 생각이 듭니다!!질문하신 내용과 코드를 보니 강의를 잘 따라 오시는 것 같고, 문제 접근 또한 잘하고 계신 것 같습니다. 끝까지 화이팅입니다!! 질문에 대해 만족스러운 답변이 되었기를 바랍니다!추가로 궁금하신 점이나 더 자세한 설명이 필요하시다면 언제든지 말씀해 주세요. 😄5점 수강평을 남겨주시면 향후 더 나은 강의를 만드는 데 큰 도움이 됩니다. 🌟
- 0
- 3
- 69
질문&답변
3020번 풀이 코드관련 질문있어요
안녕하세요, gogo_님! get_idx(arr, h) 함수는 높이가 h이하인 값 중에서 가장 오른쪽 인덱스를 반환하는 함수입니다. 예를 들어 arr = [1, 2, 3, 3, 3, 4, 4, 5]이고 h=3인 경우에 get_idx(arr, h)는 인덱스 4를 반환하는 것이죠.이제, 이러한 함수를 이용해서 천장에 있는 장애물과 바닥에 있는 장애물의 파괴해야 하는 개수를 각각 어떻게 계산하는지 예시를 통해서 자세히 알아보겠습니다. h = 4bots = [1, 3, 3, 4, 4, 5, 7, 7]tops = [2, 2, 3, 4, 4, 5, 5, 7] [바닥]먼저, h=4이므로 바닥에서는 [4, 4, 5, 7, 7] 총 5개의 장애물을 파괴하는데요. 이는 get_idx(bots, h - 1)를 이용해서 구할 수 있습니다. get_idx(bots, h - 1)을 하게 되면 높이가 3이하인 값 중에서 가장 오른쪽 인덱스를 반환하게 되며, 따라서 인덱스 2를 반환하는 것이죠.이렇게 반환된 2가 가지는 의미는 무엇일까요? 바로, h = 4일 때, 인덱스 0, 1, 2인 장애물은 파괴되지 않았다는 것인데요! 즉, get_idx(bots, h - 1)이 2이므로 bots에 있는 8개의 장애물 중에서 3개의 장애물은 파괴되지 않았다는 것이며, 이는 5개의 장애물이 파괴되었다는 것입니다. get_idx()함수는 인덱스를 반환하므로 개수를 셀 때는 1을 더해줘야 한다는 점을 주의하자. 즉, 파괴되지 않은 장애물의 개수는 get_idx(bots, h - 1)이 아닌 get_idx(bots, h - 1) + 1인 것이다.이를 코딩에서 사용할 수 있게끔 쓰면 h일 때 파괴되는 장애물의 개수는 len(bots) - (get_idx(bots, h - 1) + 1) 과 같이 쓸 수 있는 것이죠.강의 자료에 나온 코드에서는 len(bots) 대신에 N / / 2로 썼으며, 둘은 똑같은 값을 의미합니다. [천장]비슷하게, 천장에서 파괴해야 하는 장애물의 개수를 구해봅시다. 천장에서는 장애물 [2, 2, 3, 4, 4] 을 파괴하는데요. 이는 높이가 4이하인 장애물의 개수를 세면 되는데요. 따라서, get_idx(tops, h)를 이용하면 됩니다. get_idx(tops, h)를 하게 되면, 높이가 4이하인 값 중에서 가장 오른쪽 인덱스를 반환하므로 4를 반환하게 되는데요.이렇게 반환된 4가 의미하는 것이 무엇일까요? 바로, h = 4일 때, 인덱스 0, 1, 2, 3, 4인 장애물이 파괴됐다는 건데요! 따라서, h = 4일 때 파괴된 장애물의 개수는 5개인 것이죠.이를 코딩에서 사용할 수 있게끔 쓰면 h일 때 파괴되는 장애물의 개수는 get_idx(tops, h) + 1 과 같이 쓸 수 있는 것이죠. 정리하면, 1을 더하는 이유는 get_idx() 함수는 인덱스를 반환하는 함수이고, 저희는 개수를 세야 하므로 반환된 인덱스에 1을 더해준다고 생각해주시면 될 것 같습니다. 질문에 대해 만족스러운 답변이 되었기를 바랍니다!추가로 궁금하신 점이나 더 자세한 설명이 필요하시다면 언제든지 말씀해 주세요. 😄5점 수강평을 남겨주시면 향후 더 나은 강의를 만드는 데 큰 도움이 됩니다. 🌟
- 0
- 2
- 92
질문&답변
재귀 관련 문제 관찰할 때 질문
안녕하세요, 노력왕님!순열 알고리즘에 대해 직관적으로 와닿지 않아 고민이 있는 것 같은데요.이에 대해, 제가 조합, 순열, DFS 등을 포함한 재귀함수를 어떻게 이해하고 공부했는지를 알려드리겠습니다. [재귀함수의 구조에 대한 이해]재귀함수는 기본적으로 함수이기 때문에 입력 변수(들)이 있으며, 재귀(자신을 재호출)이기 때문에 recursive case, 그리고 재귀(자신을 호출하는 과정)를 끝내야 하므로 base case 부분이 존재합니다.따라서, 어떠한 로직을 재귀함수로 구현한다면 입력 변수(들), recursive case, base case 등을 고려하면 되는 것이죠.그리고 입력 변수(들), recursive case, base case 등은 "함수의 의미를 어떻게 설정할 것인가"에 따라서 달라집니다. [permutation 함수 파헤쳐보기]예를 들어, permutation(level) 함수 에 대해 생각해 봅시다.permutation(level) 함수는 어떤 의미를 가질까요? "전역변수 arr의 원소들에 대해 R개를 나열하는 순열을 전역변수 choose 배열을 통해 모두 살펴보는 함수" 라는 의미를 가집니다. 따라서, 이러한 의미에 맞게 입력 변수(level)에 대해 base case, recursive case를 작성해 봅시다.(recursive case) 만약 level이 골라야 할 원소의 개수에 아직 못 미치면, choose[level]에 들어갈 원소를 넣습니다. (base case) 만약 level이 골라야 할 원소의 개수에 도달했다면, 현재 choose는 완성된 상태이므로 적절히 처리합니다.더 자세히 설명하면, 골라야 할 원소의 개수가 R이라고 하면 choose[R-1]까지 원소를 채워야 완성이 된 것입니다. 따라서, (recursive case) level이 R-1보다 작으면(choose 배열이 완성된 상태가 아니면) recursive case를 통해서 원소를 넣고 다음 재귀함수(permutation(level + 1))로 넘겨주는 것이며, (base case) level이 R-1이면 choose[0]부터 choose[R-1]까지가 다 완성된 상태이므로, 해당 choose 배열(순열 중에서 1가지 경우에 해당)에 대해 처리를 하는 것이죠. [정리]정리하면, 재귀함수의 의미를 적절히 정의하고, 그 의미에 맞게끔 입력변수(들), recursive case, base case 부분을 정의하면 재귀함수를 작성하는 것과 이해하는 것 모두 쉬워질 것이라고 생각이 듭니다.강의에서 재귀함수에 대해 설명할 때 해당 함수의 의미를 주석으로 적는 경우가 많이 있으니, 그 의미를 생각하며 재귀함수를 이해하면 더 잘 이해할 수 있을 거라는 생각이 드네요! [수강생 분의 질문에 대한 답변]재귀함수에 대해 제가 어떻게 생각하고 이용하는지 적으려다 보니 서두가 길어졌네요. ㅎㅎ "실제로 문제를 풀 때 이렇게 하나하나 재귀깊이를 따라가면 시간이 많이 소요될 거 같은데 이러한 부분과 관련해서 팁이 있을까요?": 위에서 설명했듯이, 저는 재귀를 이해할 때 하나하나 해보면서 이해하는 것이 아닌 재귀함수의 의미를 통해 재귀를 도는 부분(recursive case)과 재귀가 끝나는 부분(base case) 딱 2가지 부분만 집중적으로 생각하여 구현합니다. 사실은, 재귀를 시작하는 부분 (즉, 재귀함수를 처음 호출하는 부분)도 생각해주시면 좋습니다. 예를 들어, permutation(level)같은 경우는 choose[level]을 완성하는 함수이므로, 처음에는 choose[0]부터 완성해야 하므로 permuation(0)을 호출해야 하는 거겠죠?하지만, 처음에는 재귀함수에 대해 어색하여 위와 같이 간단하게 생각하면 해당 재귀함수가 이해가 되지 않을 수도 있는데요.(직관적으로 와닿지 않을 수 있는데요.) 그럴 때는 질문자분이 하신 것처럼 어떻게 돌아가는지 스택 프레임 등을 직접 그려보는 방식으로 먼저 이해하시고, 제가 한 것처럼 큰 틀에서도 이해하는 것이 좋을 것 같습니다. "실제로 풀 때는 permutation(level + 1)을 재귀로 쓰면 대충 "[1, 2, 3], [1, 2, 4]... 순으로 나오겠지"와 같은 경험에 기반한 예측을 바탕으로 바로 사용하시는 건지 사고 과정이 궁금합니다.": 경험에 기반하여 믿고 구현하는 것도 있으며, 정확하게는, 이전에 permutation(level) 함수에 대해 완벽히 이해했기 때문에 믿고 구현한다고 생각하시면 좋을 것 같습니다. 재귀함수에 대해 (제 기준) 간단하고 쉽게 이해하는 방법은 위에 설명해 놓았으니 참고하시면 좋을 것 같습니다! 참고로 permutation 함수를 시행하면 [1, 2, 3], [1, 2, 4] 순으로 나오는 것은 recursive case에서 인덱스가 작은 순으로 원소를 넣기 때문이라고 생각해 주시면 됩니다. 질문에 대해 만족스러운 답변이 되었기를 바랍니다!추가로 궁금하신 점이나 더 자세한 설명이 필요하시다면 언제든지 말씀해 주세요. 😄5점 수강평을 남겨주시면 향후 더 나은 강의를 만드는 데 큰 도움이 됩니다. 🌟
- 0
- 1
- 134