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 4 #432

Merged
merged 1 commit into from
Sep 7, 2024
Merged

[haklee] week 4 #432

merged 1 commit into from
Sep 7, 2024

Conversation

haklee
Copy link
Contributor

@haklee haklee commented Sep 5, 2024

답안 제출

  • 125. Valid Palindrome
  • 268. Missing Number
  • 128. Longest Consecutive Sequence
  • 79. Word Search
  • 152. Maximum Product Subarray

체크 리스트

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

@haklee haklee requested a review from a team as a code owner September 5, 2024 16:17
@github-actions github-actions bot added the py label Sep 5, 2024
@haklee haklee requested a review from BEMELON September 5, 2024 16:18
Copy link
Contributor

@HC-kang HC-kang left a comment

Choose a reason for hiding this comment

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

@haklee 님 안녕하세요!
이번 한 주도 고생하셨습니다.

항상 잘 배우고있었는데, 이번주에는 덕분에 마침 고민하던 부분도 같이 해결됐네요!

or search(ind + 1, (pos[0] + 1, pos[1])) # 하
or search(ind + 1, (pos[0], pos[1] - 1)) # 좌
or search(ind + 1, (pos[0], pos[1] + 1)) # 우
) # 다음 글자 찾기
Copy link
Contributor

Choose a reason for hiding this comment

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

오 이부분 제가 딱 원하던 방식이었는데 이렇게 하면 되는군요

...
for (let i = 0; i < 4; i++) {
  const [dh, dw] = directives[i];
  if (dfs(h + dh, w + dw, index + 1)) {
    return true;
  }
...

취향 문제겠지만, 제 풀이중에 이 부분이 정말 마음에 들지 않았는데 덕분에 아래처럼 수정 할 수 있을것같습니다!

const found = (
  dfs(h + 1, w, index + 1) ||
  dfs(h - 1, w, index + 1) ||
  dfs(h, w + 1, index + 1) ||
  dfs(h, w - 1, index + 1)
);

Copy link
Contributor

@DaleSeo DaleSeo left a comment

Choose a reason for hiding this comment

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

수고하셨습니다!


class Solution:
def isPalindrome(self, s: str) -> bool:
return (l := [c.lower() for c in s if c.isalnum()]) == l[::-1]
Copy link
Contributor

Choose a reason for hiding this comment

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

뭡니까 이거 ㅋㅋㅋ 약 오르네요 ㅎㅎㅎ

Comment on lines +11 to +12
- 그런데 l이 격자 전체 칸 개수보다 클 수 없으므로 무시 가능.
- 총 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.

l이 격자 전체 칸 개수보다 클 수 없다고 해서 무시하는 것 보다는 O(m * n + l)이 더 정확한 분석이 아닐까요? 시간 복잡도 분석하실 때는 l을 무시하시지 않으셨잖아요.

Copy link
Contributor Author

@haklee haklee Sep 6, 2024

Choose a reason for hiding this comment

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

시간복잡도에서는 곱해야 하니까 l을 표현해줄 필요가 있는데, 공간복잡도는 다음과 같이 생각했습니다.

  • 설명을 따라가면 공간복잡도는 O(m * n) + O(l)이 되어야 합니다.
  • 그런데 이때 호출 스택이 m * n + 1보다 커질 수 없습니다. 왜냐하면 모든 칸을 다 탐색한 상태에서는 더 이상 탐색할 수 있는 칸이 없어서 False를 리턴하게 되어 호출 스택이 더 길어지지 않기 때문입니다.
  • 그렇다면 저 위에서 말한 호출 스택 크기 O(l)은 아무리 커도 O(m * n)보다 커질 수 없으므로 O(l) < O(m * n)을 만족합니다. 쓰다 보니까 O(l)이라고 하는 것에 약간 오해의 소지가 있네요.. 그냥 호출 스택 크기라고 하는 것이 나을 뻔했습니다.
  • 그리고 호출 스택 크기는 당연하게도 O(1)보다는 큽니다.
  • 정리하면 O(1) < 호출 스택 크기 < O(m * n)를 만족하게 됩니다.
  • 그러므로 O(m * n) + O(1) = O(m * n) < O(m * n) + 호출 스택 크기 < O(m * n) + O(m * n) = O(2 * m * n) = O(m * n)이 됩니다. 즉, 전체 공간 복잡도는 O(m * n)이 됩니다.

Copy link
Contributor

@DaleSeo DaleSeo Sep 6, 2024

Choose a reason for hiding this comment

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

아하 그렇군요! 자세히 사고 과정을 설명해주셔서 감사합니다 🙇‍♂️ 제 생각이 짧았네요...

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

@DaleSeo DaleSeo Sep 10, 2024

Choose a reason for hiding this comment

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

@haklee @obzva 제가 오늘 알고달레 글을 정정하려다가 이 거에 대해서 다시 생각해보게 되었는데요. 우리가 너무 호출 스택의 크기에만 초점을 맞춰서 논의한 게 아닌가 하는 생각이 들었습니다. 사실 이 답안의 공간 복잡도는 다음 2가지 측면에서 분석이 되야할 것 같아요.

  1. visited 리스트가 차지하는 메모리: O(m * n)
  2. search 재귀 함수의 호출 스택이 차지하는 메모리: O(l)

제가 재귀 함수의 호출 스택이 차지하는 메모리를 @haklee 님과 다르게 O(l)로 생각하는 이유는 다음과 같아요. 저는 3가지 경우로 나누어서 분석을 해봤어요.

  1. 단어가 격자에 존재하는 경우: 호출 스택 깊이 = l
  2. 단어가 격자에 존재하는 않는 경우: 호출 스택 깊이 < l
  3. 단어가 너무 길어서 격자가 품을 수 없는 경우: 호출 스택 깊이 = m * n < l

결국 스택 깊이의 상하선을 결정짓는 것은 m * n보다는 l로 보는 것이 더 합리적이라는 결론을 내렸어요.

제가 over thinking 했을까요? 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@DaleSeo 늦은 확인 및 답변 죄송합니다..! ㅠㅠ
저도 위에서 세 가지 경우로 나눠서 분석하신 것과 같은 생각을 했는데, 제가 호출 스택의 깊이를 신경쓰지 않고 공간복잡도를 계산했던 이유는 호출 스택으로 도출되는 공간복잡도가 O(m * n)보다 작은데 visited 리스트에서 O(m * n)을 이미 먹고 있어서 자연스럽게 무시할 수 있게 되어서 였습니다.
위에서 말씀하신 것에 따르면 호출 스택 깊이는 O(min(l, m*n)) 같이 표현하는 것은 어떨까요?

@haklee haklee merged commit b37ae9b into DaleStudy:main Sep 7, 2024
3 checks passed
@DaleSeo DaleSeo mentioned this pull request Sep 7, 2024
9 tasks
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.

4 participants