Skip to content

[Invidam] Solve Week01 Problems (5/5) #GoLang #36

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

Merged
merged 13 commits into from
May 3, 2024
Merged

[Invidam] Solve Week01 Problems (5/5) #GoLang #36

merged 13 commits into from
May 3, 2024

Conversation

Invidam
Copy link
Contributor

@Invidam Invidam commented Apr 30, 2024

Contains Duplicate

문제 해결 방법

  • 배열을 순회하며 원소들(appeared)를 집합에 저장한다.
  • 저장 과정에서 집합에 이미 있던 원소라면 참을 반환한다.
  • 순회가 끝났다면 모든 원소가 한 번씩만 등장한 경우이므로 거짓을 반환한다.

자료구조 선택

  • 배열을 이용
    • 장점: 다른 자료구조보다 가볍다.
    • 단점: 동적으로 확장할 수 없다. 입력값에 의존한다.
  • Hash Set을 이용
    • 장점: 동적 확장이 가능하다. O(1)에 검색, 삽입이 가능하다.
    • 단점: 해쉬 충돌
  • Tree Set을 이용
    • 장점: 크게 없음. (값들이 정렬되어 저장된다는 이점을 활용할 수 없다.)
    • 단점: O(logN)의 검색, 삽입 비용.

성능

a8669da
해시맵을 이용
시간복잡도: $O(N)$
공간복잡도: $O(N)$

  • N은 배열의 크기

개선

  • 해시 맵의 크기 설정.: 2b171cc
    • 배열의 개수만큼 맵의 크기를 설정해주니 메모리가 줄어들었다. (배열처럼 활용)
      • 단, 중복 여부가 일찍 발견되는 경우 미리 크기를 할당한 이점이 줄었다.
        • 이러한 결과가 속도 감소로 나타났다.
    • 1/4 정도로 줄이니 메모리/시간 모두 뛰어났다.
      • 일찍 발견한 경우(맵을 0으로 초기화), 모두 순회하는 경우(맵을 모두 채움)의 타협점.
  • 좋은 코드 관점: 733fc96
    • 하나의 반복문에서 모두 처리하는 게 SRP 측면에서 바람직하지 않다.
      • 반복문을 2개로 나눈다.
      • 해시 셋에 모든 원소들을 넣고, 배열의 크기와 셋의 크기를 비교하여 중복을 확인한다.
        • 배열의 크기보다 셋의 크기가 작다면, 여러 번 등장한 원소가 있는 것이다.

또 다른 풀이

정렬 활용 (솔루션 참고)
배열을 정렬한 후, 이전 원소와 비교한다. 이전 원소와 같다면 중복인 것이다.
시간복잡도: $O(nlogn)$
공간복잡도: $O(n)$ (inline)

(inline: 새로운 메모리 사용이 없음을 표현.)

알게된 것

  • make 함수의 사용법: size, capacity 조정
  • map을 순회하는 방법: elem, ok := m[a]

Valid Anangram

문제 해결 방법

문자의 횟수 비교는 많이 봤던 문제.
hash map을 이용하여 빈도 수를 저장하고, 그 차이를 비교한다.

자료구조 선택

hash map

성능

0280206
시간복잡도: $O(N+M)$
공간복잡도: $O(N+M)$
(N,M은 각각 s,t의 길이)

개선

  • 두 해시 맵의 크기를 비교하여 필터링하는 경우도 가능함.

또 다른 풀이

정렬 한 후 동등 여부를 비교하는 풀이도 있었음. (솔루션 참고)

  • 시간, 공간복잡도는 각각 $O(NlogN), O(N)$
    • 공간복잡도는 inline.

알게된 것

GoLang은 rune 으로 문자를 저장한다.
rune은 int32의 별명이다.

Two Sum

문제 해결 방법

  • 처음에, 저장 개념(hash map)을 이용하면 풀 수 있겠구나 싶었다.
  • 그러다, 이중 반복문이 가장 간단하다고 생각했다.
  • 시간 내에 될까싶어 한 번 돌려보았고 성공하였다.

자료구조 선택

성능

cf7e53e
시간복잡도: $O(N^2)$
공간복잡도: $O(N)$

  • N: 배열의 크기
  • inline

또 다른 풀이

투포인터 58ad6dc

  • 배열을 정렬한 후, 맨 왼쪽에 하나의 인덱스, 맨 오른쪽에 하나의 인덱스를 둔다.
  • 두 인덱스를 조절해가며 l + r = target이 되는 l, r을 찾는다.
  • O(NlogN), O(N)
    해쉬 이용 (솔루션 참고) f3f5d84
  • 나를 원하는 경우가 있다면 내 인덱스를 남긴 인덱스와 함께 반환한다.
  • 없다면, 내가 원하는 숫자에 인덱스를 남긴다.
  • O(N), O(N)

특이사항

해쉬 충돌이 많아서인지, 투포인터가 더 빨랐다.

알게된 것

배열을 값들과 함께 선언하는 방법.

Valid Palindrome

문제 해결 방법

  • 요구사항대로 소문자 & 숫자만을 남긴다.
  • 이후 좌, 우에서 이동하며 동일한지 확인한다.

성능

921f9b9
시간복잡도: $O(N)$
공간복잡도: $O(N)$

  • N은 배열의 크기
  • inline

개선

문자열을 더하는 방법

  1. StringBuilder: 921f9b9
  2. + 연산자: a19cf61
  3. Mapping Function: 555ea05

특이사항

Mapping Function은 내부적으로 Builder을 사용해서, StringBuilder와 성능이 동일했다.

알게된 것

  • GoLang에서 문자열을 더하는 방법 (StringBuilder, + 연산자, Mapping Function)과 그들의 성능

best-time-to-buy-and-sell-stock

문제 해결 방법

  • 이중 반복문으로 짰더니 시간 초과가 났다.
  • dp를 생각했다. 특정 인덱스에서부터 최댓 값을 dp를 이용해 계산한다. 추가

성능

8678b9a
시간복잡도: $O(N)$
공간복잡도: $O(N)$

(N은 배열의 크기)

개선

또 다른 풀이

59f2aed

  • dp를 사용하지 않고 해결하는 솔루션을 확인했다. 배열을 순회하며, 최소 금액과 최대 이익을 갱신하는 방식이다.
    • 시간, 공간 복잡도는 각각 $O(N), O(N)$이다.

특이사항

생각해보니, 비슷한 문제를 "또 다른 풀이"처럼 푼 기억이 있었다. 문제의 도메인(금액 거래)에 너무 매몰되지 말아야겠다.

후기

  • 초반에 비해 공부의 깊이가 줄었던 것 같았다.
  • 하루에 2,3문제를 같이 풀고 나중에 분석을 하니 기억이 잘 안났다. 하루에 1문제씩 풀고 분석 글도 같이 적어야겠다.
  • 코드 리뷰를 많이 받고싶은 만큼 많이 해드려야겠다고 느꼈다.

@DaleSeo DaleSeo added the week1 label Apr 30, 2024
@DaleSeo DaleSeo added this to the week1 milestone Apr 30, 2024
Copy link
Member

@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.

정성스러운 PR 설명을 통해서 @Invidam 님께서 어떤 고민을 하셨고, 어떤 다른 풀이들을 시도하셨으며, 그 과정에서 어떤 것들을 배우고 느끼셨는지 한 눈에 볼 수 있어서 참 인상 깊었습니다. 제가 go 언어를 쓸 줄 모르지만 PR 설명을 보면서 코드를 읽으니 대강 이해가 되네요.

디스코드 채널에서 PR 설명을 너무 장황하게 적었나 했다고 하셨는데, 코드에 주석도 적절히 활용하시면 더 좋겠다는 생각을 해봤습니다. 예를 들어, 최종 답안에 대한 복잡도 분석은 각 함수 위에 주석으로 달아놓으시면, 나중에 혹시 PR을 안 보고 코드만 참조하시는 분들에게는 도움이 될 것 같습니다.

Copy link
Contributor

@SamTheKorean SamTheKorean left a comment

Choose a reason for hiding this comment

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

PR에 설명을 상세하게 적어주셔서 저도 읽으면서 정리가 된 것 같습니다 ㅎㅎ 다만 달레님 말씀처럼 소스코드에도 주석을 추가해도 좋을 것 같습니다 ㅎㅎ

@SamTheKorean SamTheKorean merged commit 03cbc7f into DaleStudy:main May 3, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants