Skip to content

알고리즘 풀고 기록하는 곳입니다. 요즘은 주로 Leetcode와 함께한다 !

Notifications You must be signed in to change notification settings

sery270/Algorithm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

fec4cd9 · Jun 13, 2022
Feb 18, 2021
Mar 24, 2022
May 5, 2021
Jun 13, 2022
May 29, 2022
May 18, 2021
Jul 27, 2020
Jan 3, 2021
Jan 3, 2021
Apr 21, 2021
Mar 27, 2022
Sep 12, 2021
May 18, 2021
Jul 21, 2020
Jul 21, 2020
Mar 26, 2022

Repository files navigation

😇 세리의 Algorithm 공부😇

코딩 테스트 대비로 시작했는데, 나름 재밌게 게임 하듯 공부하고 있는 알고리즘님! 잘 부탁해 !

Algorithm 스터디 TIL(Today I Learned)

🎮 2022/03/26 토

  • 올해 sk1,2차에 이은 3번째 코테 ! 라인 공채 코테를 보았다. 생각보다 초반 문제 난이도는 쉽게 느껴졌다. 라고 할 뻔~~ 후반부에 시간이 애매하게 30분 남아서 푼 문제들 TC를 왕창 적고 돌려보다가 3개 정도의 예외처리를 추가했다. 내 로직은 항상 "콩쥐야 조때써"의 상황과 같고, 그렇게 TC 검증 단계의 중요성을 다시 깨달았다.
  • 2번 문제.. 효율성을 고려하지 않은 부분이 아쉬웠다. itertools를 사용했는데, 별다른 방법이 생각이 나지 않았다는 것이다. 뭔가 카카오 작년 공채 양궁게임이랑 비슷한 느낌의 문제였다.
  • 작년에 비해, 아니 당장 2주전과 비교해서라도 피지컬이 많이 좋아진 것 같다. 기나긴 구현 문제를 읽고 소화하기 + 파이선의 다양한 활용법 암기 + 포기하지 않고 부분 코드들 제작하고, 조합하기 + 차분하게 TC작성 및 디버깅하기 등등의 액션이 실전에서도 적용되었다는 의미이다. 좋은 방향이라 생각든다.
  • 한편 어젯밤부터 오늘 아침까지 알고리즘 책을 보면서 문자열, 우선순위 큐, 투포인터 같은 자료구조나 간단한 알고리즘을 암기하려했는데, 책 따라가다보니 재밌었고, 꾸준히 공부해야할 범위라고 생각했다.. 평소에 위에서 말했던 피지컬을 유지하면서 알고리즘 책을 꾸준히 읽고 싶어졌다 ! 음 그리고 굳이 문제를 끝까지 붙잡기보다 다른 사람의 코드를 흡수하는 편이 내 공부법과 잘 맞았다. (못풀겠는거 계속 붙잡는다고 풀리는거 아니고, 오히려 나에게 사기를 떨어뜨리는 행위이다,,)
  • 예상했듯이 구현 문제만 와르르 나왔다. 코테 대비한다면, 뭐 구현 중심으로 투포인터, 슬라이딩 윈도우, 자료구조 같은거 공부하고, 알고는 재귀 풀이,,그리고 dfs, bfs, 이진탐색 이면 괜찮지 않나 싶다..(?) 너무 어려운 알고리즘은 실전에서 적용하기도 어려울뿐더러, 실제로 구현 중심의 문제가 출제한다는 인터뷰도 이 주장을 뒷받침한다.
  • 지난 주에 치뤘던 올해 sk 공채 코테에선 프로세스 스케줄링 알고리즘 구현 문제가 나왔었고, 2018 카카오에선 LRU 캐싱 알고리즘 구현 문제가 나왔던걸로 기억한다. 운체에서 등장하는 특정 알고리즘들에 대해서 구현하는 문제 한 번씩 풀어봄직하다. (os 지식, 자료구조 지식, 구현 능력을 확인할 수 있기 때문에 상당히 멋진 코테 주제라고 생각된다.)

🎮 2021/05/09 일

  • 오늘은 모의 코딩 인터뷰를 해보았다. 생각보다 유익했다 !
  • 보통 문제를 보자마자 드는 생각을 바로 코드로 적어왔는데, 이렇게 기존 방식대로 코딩인터뷰를 진행했을때의 문제와 개선 방법을 피드백 받았다.
  • 기존 방식의 문제
    • 소통이나 충분한 주석 없이 바로 코드를 작성하기 시작하면, 면접관을 이해시킬 수 없다.
    • 머릿속으로만 생각하면, 예외 TC를 고려하기 어렵다.
    • 질문 없이 문제를 이해하고 넘어가면, 질문자의 의도에 다르게 문제를 풀게 될 수 있다. 수렁으로 빠질 수 있다.
  • 개선
    • 코딩 인터뷰는 면접관과 함께 소통하며, 문제를 구체화 시키고 해결해가야하는 시간이다.
    • 핵심은 시각화이다. brain storming한 내용을 sudo 코드로 작성하는 것 핵심이다.
    • 아래 방식을 따라가면 좋다.
      1. Problem is
        • 문제 상세 조건 확인하기
        • 질문하면서 소통하기
      2. TC
        • TC를 새로 작성해가면서 내가 이해한 문제가 맞는지 질문자에게 확인하기
      3. Brain Storming
        • 이해한 문제를 TC가지고 해결하는 과정을 시각화 하면서, 솔루션을 도출해내기
      4. Sumarize my idea (Write SUDO Code)
        • 3의 결과에 SUDO를 첨부하기
      5. Write Code
        • 4를 뼈대로 for문의 인덱스나, 추상적으로 정의만 해뒀던 변수들에 대한 초기화를 하기 (SUDO 코드 보완)
      6. Debuging
        • 2에서 만든 TC로, 3의 방식으로 디버깅하기
        • 사실 print() 떡칠해서 디버깅하는 것보다, 더 빨리 문제 지점을 찾을 수 있다.
          • 특히 코드로 구현하면서 발생한 문제라면, 3에서 도출한 방법 그대로 디버깅하는 것이기 때문에 더 효과적으로 구현에 대한 디버깅을 할 수 있는 것이다.
          • 솔루션 자체의 문제일 때도, bottom-up으로 빠짐없이 체크할 수 있기 때문에 효과적이기도 하다.

🎮 2021/05/08 토

  • 오늘 카카오 여름 인턴십 코딩테스트를 치뤘다. 예상처럼 구현 문제가 많이 출제되었다. (하)
  • 네이버보단 지문도 짧고, 테케도 주어져서 좋았다.
    • 히든 테케 없이 공개된 테케로만 채점이 돼서 맘은 편했으나, 해당 테케 실행 시간이나 등등이 좀 거슬렸다.
  • 네이버때도, 지금도, 항상 커트라인에 애매하게 걸치거나 안된다. 조금만 더,, 조금만 더,,, 피지컬을 내야 안정적인 결과를 얻을 수 있을 것이다. (너무 아쉽다.)
  • 그리고 이번에 칭찬하고 싶은 점은, 아무리 빡 구현 문제라 해도, 무조건 문제 말 그대로 빡 구현 하기 보단, 문제를 추상화 시켜서 최소 연산 횟수 방법이나 자료 구조 같은걸 고려하면 풀었다는 점이다.
    • 이러한 접근 방법이 틀리지 않았다는 것에, 가능성을 싣고, 이 가능성을 시간내에 실현하기 위한 피지컬 연습을 많이 해야겠다고 느꼈다.

🎮 2021/04/24 토

  • 오늘 네이버 상반기 신입 공채 코딩테스트를 치뤘다. 예상과는 달리 알고리즘을 묻는 문제가 아닌 구현 문제가 많이 출제되었다. 이 긴 지문을 차분히 빠짐없이 이해할 수 있는지, 로직을 생각할 수 있는지, 그것을 코드로 구현할 수 있는지,  코드로 구현한다면 효율성도 생각해볼 수 있는지 등등을 본다는 느낌으로 응시했던 것 같다.
  • 2번 문제같이 까다로운 문자열 문제를 열심히 봐야겠다 !
  • 아무 생각없이 3번 문제에 itertools combinations 를 썼는데, 효율성에 대한 고민도 해봐야겠다.

🎮 2021/04/22 목

  • PG 단어변환을 풀면서, str의 특정 문자를 삭제하는 두가지 방법을 알게 되었다. 1개의 테스트 케이스를 통과 하지 못하고 있었는데, replace 함수에 대해 잘 모르고 쓴 것이 문제였다. replace와 인덱스 슬라이싱을 활용한 방법은 중복 출현된 문자에 대해서 다른 결과를 가져올 수 있다.

    • 특정 인덱스의 문자를 삭제하기

      now_tmp = now[:i] + now[i+1:]
      word_tmp = word[:i] + word[i+1:]
    • 특정 문자를 모두 삭제하기

      # replace는 비파괴적 함수이므로, 새로운 대입이 필요함
      now_tmp = now.replace(now[i],"")
      word_tmp = word.replace(word[i],"")
  • 특정 원소의 값이 리스트의 몇번째 인덱스에 위치하는지 알려주는 함수 find()를 활용한 조건문은 아래와 같다.

    • index(now)는 words에 now가 없을 때 valueError 발생시키므로, if문에 사용할 수 없다.
    • find(now)는 words에 now가 없을 때 -1을 반환하므로, 이를 활용하여 if문에 사용할 수 있다.
    # word는 str형 list, str형
    # before는 str형 list
    # now는 str
    
    # if문에선 0이 false고, 0 이외의 것들은 true이므로, +1을 해서 분기처리 해줌 
    if words.find(now)+1:
      print(words.find(now))
      print("if")
    else:
      print(words.find(now))
      print("else")

🎮 2021/04/21 수

  • BOJ 9019를 풀다가, L과 R 연산 (왼쪽 회전, 오른쪽 회전 : 1234 → 2341, 1234 → 4123)을 구현하면서 고통받았었다. 이 회전 연산을 deque의 rotate를 사용하여 리펙토링 해보았다. 과정은 아래와 같다.
    1. 입력된 숫자 N을 str로 표현하기 → N_str

      N = int(input()) # input : 12
      print(N)
      print(type(N))
      # 12
      # <class 'int'>
      
      N_str = str(N)
      print(N_str)
      print(type(N_str))
      # 12
      # <class 'str'>
    2. len(N_str)에 따라 (N의 자릿수에 따라) 0을 패딩해주기 → 패딩된 N_str

      N_str = N_str.zfill(4)
      print(N_str)
      print(type(N_str))
      # 0012
      # <class 'str'>
    3. N_str을 deque로 표현하기 → N_dq

      N_dq = deque(N_str)
      print(N_dq)
      print(type(N_dq))
      # deque(['0', '0', '1', '2'])
      # <class 'collections.deque'>
    4. N_dq를 회전하기

      N_dq.rotate(1)
      print(N_dq)
      print(type(N_dq))
      # deque(['2', '0', '0', '1'])
      # <class 'collections.deque'>
    5. N_dq를 다시 int로 변환하기

      N_str = "".join(N_dq)
      print(N_str)
      print(type(N_str))
      # 2001
      # <class 'str'>
      
      N = int(N_str)
      print(N)
      print(type(N))
      # 2001
      # <class 'int'>

🎮 2021/04/20 화

  • 파이선의 for-else, while-else 문을 들어보셨나요. 오늘 BOJ 9019를 풀면서 발견한 트릭이다. 각 반복문-else에선, 반복문이 끝까지 정상적으로 돌았을때, else의 내용을 실행한다.

    • 아래는 for - else 의 예제이다. 반복문이 정상적으로 종료되고 for-else의 else가 실행된 결과이다.
    i = 0
    for i in range(0,5):
      print(f"it's {i}")
      i += 1
    else:
      print('while-else !')
    
    # it's 0
    # it's 1
    # it's 2
    # it's 3
    # it's 4
    # while-else !
    
    • 아래는 while-else의 예제이다. 반복문이 break로 인해 비정상적으로 종료되고 while-else의 else가 실행되지 않았다.
    i = 0
    while True :
      print(f"it\'s {i}")
      if i == 5:
        print("it's break time")
        break
      i += 1
    else:
      print('while-else !')
    
    # it's 0
    # it's 1
    # it's 2
    # it's 3
    # it's 4
    # it's 5
    # it's break time

🎮 2021/04/18 일

  • 2178_미로 탐색을 풀면서, 파이선의 for를 통한 리스트 생성 방식과 * 를 통한 리스트 생성 방식의 차이점을 알게되었다. * 를 통한 리스트 생성은 주소까지 복사되어, 추후에 값 초기화시에 원치 않는 위치도 초기화 될 수 있으므로, for를 통한 리스트 생성을 사용해야겠다고 결론지었다.
    1. for를 통한 리스트 생성

      before = [[[0] for _ in range(5) ]for _ in range(7)] 
      before[0][0] =(1,2)
      print(before)
      [
      [(1, 2), [0], [0], [0], [0]], 
      [[0], [0], [0], [0], [0]], 
      [[0], [0], [0], [0], [0]], 
      [[0], [0], [0], [0], [0]], 
      [[0], [0], [0], [0], [0]], 
      [[0], [0], [0], [0], [0]], 
      [[0], [0], [0], [0], [0]]
      ]
    2. * 를 통한 리스트 생성

      before = [[0] * (5)] * (7)
      before[0][0] =(1,2)
      print(before)
      [
      [(1, 2), 0, 0, 0, 0], 
      [(1, 2), 0, 0, 0, 0], 
      [(1, 2), 0, 0, 0, 0], 
      [(1, 2), 0, 0, 0, 0], 
      [(1, 2), 0, 0, 0, 0], 
      [(1, 2), 0, 0, 0, 0], 
      [(1, 2), 0, 0, 0, 0]
      ]

🎮 2021/04/17 토

  • 13919_숨바꼭질4를 풀면서, 파이선에서의 재귀는 최대한 지양해야겠다는 결론을 내렸다.
    1. 런타임 에러 (RecursionError)의 위험이 있다. 파이선을 재귀 호출 깊이를 제한하면서 발생하는 문제이다. 아래 코드로 재귀 깊이 제한을 풀 수 있긴하다.

      import sys
      
      MAX = 100000
      sys.setrecursionlimit(MAX*2)
    2. 파이선에서의 재귀호출은 메모리와 시간 복잡도가 크게 증가하게 한다. 특히 무한루프로 구현할 수 있는 똑같은 동작을 재귀로 구현했을땐, 공간 복잡도(메모리)가 약 2-3배 정도 증가했다. 🥲

      말도 안되는 차이

      • [BOJ] 13913_숨바꼭질4.py

        # 메모리 36628 KB
        # 시간 256 ms
        
        k = K
          while 1:
            if before[k] == N:
              path.append(before[k])
              break
            path.append(before[k])
            k = before[k]
      • [BOJ] 13913_숨바꼭질4_recursion.py

        # 메모리 118284 KB
        # 시간 332 ms
        
        def find_path(K):
          if before[K] == N :
            path.append(before[K])
            return
          path.append(before[K])
          find_path(before[K])
        
        find_path(K)

🎮 2021/04/15 목

🎮 2021/04/14 수

  • 주언어 python으로 다시 돌아왔습니다. C++이 매웠던걸 느꼈습니다.. python으로 알고리즘 푸니 수도 코드만 적는 느낌이라 편하다.
  • Python 자료형에 대한 정리

🎮 2020/08/24 월

  • [BOJ] 9465_스티커
  • [BOJ] 9465_스티커_최적화
  • 메모리 최적화 :: 40N Byte → 12N Byte
    • 점수를 담는 배열의 자료형을 long long으로 잘못 사용한 것을 int로 수정
      • 8 Byte → 4 Byte
    • 굳이 윗행, 아랫행 모두 선택되지 않은 경우를 계산하지 않음
      • 8 * 3N Byte → 4 * 2N Byte
  • 시간 최적화 :: 4N * max() 호출 → 2N * max() 호출
    • 굳이 윗행, 아랫행 모두 선택되지 않은 경우를 계산하지 않음
      • 3N * max() 호출 → 2N * max() 호출
    • 처음과 끝 열은 무조건 1개가 선택된다는 문제의 성질 → bottom-up 알고리즘이므로, 마지막 열에서의 두가지 분기를 통해 sol 계산
      • N * max() 호출 → 1 * max() 호출

Algorithm 스터디 conventions

commit convention

[BOJ] 9465_스티커

[PG] k번째 큰수

[DOCS] - readme, wiki 작성한 경우

[CHORE] - 동작에 영향을 주는 코드 변경 없는 변경사항 (주석, 정렬 등등)

[NOTE] - 알고리즘 노트, 알고리즘 템플릿 작성


foldering

BruteForce : 완전탐색

BruteForce에 대해 공부하고 정리한 WIKI

DP : 다이나믹 프로그래밍

DP에 대해 공부하고 정리한 WIKI

DataStructure : 자료구조

자료구조에 대해 공부하고 정리한 WIKI

Greedy : 탐욕법

Greedy 알고리즘에 대해 공부하고 정리한 WIKI

I:O : 입출력, 문자열

입출력에 대해 공부하고 정리한 WIKI


About

알고리즘 풀고 기록하는 곳입니다. 요즘은 주로 Leetcode와 함께한다 !

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published