Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[haklee] week 8 #506

Merged
merged 2 commits into from
Oct 5, 2024
Merged

[haklee] week 8 #506

merged 2 commits into from
Oct 5, 2024

Conversation

haklee
Copy link
Contributor

@haklee haklee commented Sep 30, 2024

답안 제출 문제

체크 리스트

  • PR을 프로젝트에 추가하고 Week를 현재 주차로 설정해주세요.
  • 바로 앞에 PR을 열어주신 분을 코드 검토자로 지정해주세요.
  • 문제를 모두 푸시면 프로젝트에서 Status를 In Review로 설정해주세요.
  • 코드 검토자 1분 이상으로부터 승인을 받으셨다면 PR을 병합해주세요.

@haklee haklee requested a review from a team as a code owner September 30, 2024 16:48
@github-actions github-actions bot added the py label Sep 30, 2024
@haklee haklee requested a review from obzva September 30, 2024 16:49
@@ -0,0 +1,65 @@
"""TC: O(n), SC: -

n은 주어진 두 리스트의 길이 중 큰 값
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haklee님의 n 정의로도 납득 가능한 설명이지만 개인적으로는 n을 두 리스트의 길이의 총합으로 두는 것이 자연스럽지 않을까 싶습니다

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

덧글 남겨주신 내용 보고 제가 왜 n을 저렇게 가정했을까 다시 생각해봤는데요,

  • 실제 문제에서는 두 리스트 길이가 in the range [0, 50] 정도로만 설명되어 있었습니다.
  • 두 리스트가 주어진다는 것을 보고 서로 독립적인 절차를 거쳐서 생성된 두 개의 리스트를 받아서 무슨 처리를 하는 상황일 것이라고 상상했던것 같습니다.
  • 여기서 더 이어서, 이 두 리스트 길이가 각각 최대 50이라는 조건이 주어져 있긴 하지만, 이건 리스트를 처리하는 쪽에서 제시한 최소한의 조건이고, 두 리스트를 제공하는 쪽에서 지키는 국룰(예를 들어, 리스트 길이가 아무리 길어도 30이 넘지 않도록 만든다...)이 따로 존재할 수도 있다고 상상했습니다. 그런데 두 리스트를 제공하는 쪽이 서로 독립이라고 처음에 생각했으니, list 1은 최대 길이 n_1(단, n_1은 무조건 50 이하), list 2는 최대 길이 n_2(단, n_2는 무조건 50 이하)을 지키며, n_1, n_2는 서로에 영향을 받지 않는 값이라고 볼 수 있습니다.
  • 여기에서 n을 max(n1, n2)라고 생각하고 문제를 풀었습니다.

물론 위에는 무수히 많은 가정들을 하면서 n을 정한 것이기 때문에 n을 꼭 저렇게 둘 필요는 없습니다. 말씀하신 것처럼 n을 두 리스트 길이의 총합으로 두어도 괜찮고, 처음에 주어진 in the range [0, 50]에의 50을 n으로 두어도 괜찮을것 같습니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 ㅎㅎ 개인적인 의견에도 정성스러운 답변 감사합니다
배경내용 설명을 이해하기에 충분히 제공해주셔서, 사실 N을 어떻게 정의해도 문제되지 않을 것 같습니다

@lymchgmk
Copy link
Contributor

lymchgmk commented Oct 1, 2024

전에 log 풀이보고도 느꼈지만 수학적 사고에 굉장히 능숙하신 것 같습니다. 풀이 보고 많이 배우고 있습니다. 감사합니다.

Comment on lines 127 to 133
def getSum(self, a: int, b: int) -> int:
x = list(range(0, 2001))
x.extend(list(range(-2000, 0)))
v = x * 2
s = list(range(0, 4001))
e = list(range(4001, 8002))
return v[s[a] : e[a]][b]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look up table을 생각하면서 푸신걸까요 멋진 풀이네요

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

선택한 방식으로 끝까지 방법을 연구하는 태도가 멋지다고 생각합니다 😎

Copy link
Contributor

@obzva obzva Oct 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다만 풀이를 보면서 들었던 생각은,
+, - operator의 사용을 금지하였는데, range, *같은 함수 및 operator는 사용해도 되는 것일까?
였습니다

왜냐하면 range* 내부적으로 +- 산술 연산자를 사용하고 있지는 않을까 하는 의심이 들었기 때문입니다

궁금해서 CPython 소스 코드를 좀 뒤져봤는데, range의 경우엔 명시적으로 + 연산자를 사용하지 않고 있었고 *같은 경우에는 특정 범위 내의 피연산자를 연산할 경우엔 Karatsuba 알고리즘을 사용하는 것으로 보아 +를 내부적으로 사용한다고 볼 수도 있을 것 같다고 생각했습니다

저는 막연히 *는 모두 +를 반복시켜서 구현해놓았을 줄 알았는데, 덕분에 위와 같은 사실들을 알게 되었습니다 감사합니다 :)
(추가로 C의 *는 기계가 어떻게 처리할지 궁금해서 찾아봤는데, CPU 또한 단순 덧셈을 반복하는 식으로 곱셈을 처리하지 않으며 다양한 효과적인 방식을 사용하고 있다는 것도 알게 되었습니다)

Comment on lines +42 to +48
SC:
- 노드 총 n개가 memo에 올라간다. O(n).
- 각 노드마다 neighbor가 있다. 각 edge마다 neighbor 리스트들의 총 아이템 개수에 2개씩 기여한다. O(e).
- 더하면 O(n + e). 즉, 둘 중 더 큰 값이 공간복잡도를 지배한다.
...고 생각하는 것이 일차적인 분석인데, 여기서 더 나아갈 수 있다.
- 주어진 조건에 따르면 우리에게 주어진 그래프는 connected graph다. 즉, 엣지 개수가 n-1개 이상이다.
- 즉, O(n) < O(e)가 무조건 성립하므로, O(e) < O(n + e) < O(e + e) = O(e). 즉, O(e).
Copy link
Contributor

@obzva obzva Oct 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dfs + memo 방식의 공간 복잡도 분석을 제가 잘 이해하지 못했습니다 🥹

제가 생각했을 때는,

  1. memo dictionary의 공간 사용은 N에 비례하여 선형적으로 증가 -> O(N)
  2. dfs의 재귀호출 스택의 크기는, 한 노드가 가질 수 있는 간선의 최대 개수 즉, N - 1에 비례하여 증가 -> O(N)

이라고 생각되어서 공간 복잡도에서 E는 오히려 배제하여도 되는 변수이고, 최종적으로 공간복잡도는 O(N)이라고 �생각하는데 학님은 어떻게 생각하시는지 의견 궁금합니다

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오... 생각해보니 재귀 호출 스택 크기는 어차피 n보다 커지지 않을 거라고 생각하고 분석에 안 쓰고 그냥 넘어가버렸네요...

극단적으로 n개의 노드들이 모두 서로에 연결되어 있는 상황을 생각해보면 위의 설명이 이해가 될 것이라고 생각합니다.

  • 노드 하나가 neighbor로 들고 있어야 하는 값이 크기 O(n)짜리 리스트입니다. 노드 객체를 직접 들고 있지 않고 노드 객체의 포인터만 들고 있다고 해도, 포인터 자체의 크기도 고려해야 하기 때문에 O(n)입니다.
  • 위와 같은 노드가 n개 있습니다. 즉, 각 노드가 들고 있는 neighbor를 표시하기 위해서 O(n^2)의 공간이 필요합니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

설명 감사합니다
저는 보통 return하는 객체는 공간 복잡도에 포함시키지 않는데, 이 부분에서 서로 생각의 차이가 비롯된 것 같습니다

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그렇네요..! 항상 리턴하는 값에 할당되는 공간을 무시한다는 것을 잊습니다 ㅠㅠ '리턴값에 어차피 O(n^2) 공간이 필요한데 추가 공간이 O(n) 필요하면 어차피 실제 작동하는 상황에서 추가 공간은 무시할만하다고 보는 것이 맞지 않나...?' 하는 생각이 자꾸 들어서 그런것 같습니다...

abc, bcdefy의 lcs 길이와
abcz, bcdef의 lcs 길이
둘 중 더 큰 값을 취하면 된다.
- LCS는 유명한 알고리즘이므로 위의 설명을 시각적으로 잘 표현한 예시들을 온라인상에서 쉽게
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LCS는 유명한 알고리즘

유명한데 저는 볼 때마다 까먹어서 찾아보게 되네요 ㅋㅋㅋㅋ

SC:
- 첫 번째 문자열의 앞 i글자로 만든 문자열과 두 번째 문자열의 앞 j글자로 만든 문자열의 lcs의
길이를 관리.
- O(m * n)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

결국 알고리즘을 진행하는 데에 있어서 필요한 배열은 딱 두 행( dp[i], dp[i - 1] )이므로 공간 복잡도를 O(N)까지 낮출 수 있을 것 같습니다
물론 학님께서 몰라서 이대로 두진 않으셨을 것 같긴 하지만요 😎

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

별 생각 없이 구현하고 넘어갔는데 그러고 보니 그렇네요 ㅎㅎ 반영하겠습니다!

@haklee haklee merged commit ad69c40 into DaleStudy:main Oct 5, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Completed
Development

Successfully merging this pull request may close these issues.

3 participants