본문 바로가기

카테고리 없음

코딩 테스트 합격자 되기 스터디 1주차 - 시간복잡도

코딩테스트 합격자 되기 스터디 1주차

[지금 무료] 코딩 테스트 합격자 되기 - C++ 강의 | dremdeveloper - 인프런

시간복잡도

알고리즘이란?

유한한 수의 규칙에 따라 구별 가능한 기호들을 조작하여 입력 정수에서 출력 정수를 생성하기 위한 일반화된 작업을 정의

  • 정밀성: 변하지 않는 명확한 작업 단계를 가져야 한다.
  • 유일성: 각 단계마다 명확한 다음 단계를 가져야 한다.
  • 타당성: 구현할 수 있고 실용적이어야 한다. → 알고리즘의 성능
  • 입력: 정의된 입결을 받아들일 수 있어야 한다.
  • 출력: 답으로 출력을 내보낼 수 있어야 한다.
  • 유한성: 특정 수의 작업 이후에 정지해야 한다.
  • 일반성: 정의된 입력들에 일반적으로 적용할 수 있어야 한다.

알고리즘의 성능은 어떻게 측정할 것인가?(절대 시간 측정)

PC에서 코드가 수행된 시간이 짧을수록 좋은 성능이다라고 정의한다면 동일한 코드를 수행할 때, 두 개의 PC에서 결과가 같게 나올까?

알고리즘 성능 측정을 위해서는 환경에 제약을 받지 않는 기준이 있어야 한다.

연산 횟수 측정

환경 영향을 받지 않지만 입력값에 따라 달라질 수 있으므로 기준 필요

  • 입력값에 따른 연산횟수가 일정하지 않는 경우 → 코테에서는 최악의 경우를 기준으로 연산횟수를 정하는 것이 좋음.

입력값에 따른 연산횟수를 측정해서 알고리즘의 성능을 지표로 나타내는 것을 시간복잡도라고 함.

생각해볼 점

  1. 코딩테스트에서 이렇게 정밀한 연산 횟수를 매번 측정해야하는가?
    • 점근적 표기법으로 표기. 연산 횟수 추이로 통과 여부만 파악하면 됨
  2. 시간복잡도 활용법
    • 입력값을 기준으로 가용한 자료구조 및 알고리즘 고려 가능

점근적 표기법

N^2 + 3N + 5를 봤을 때

N을 무한으로 보내면 가장 큰 차수만 남겨도 무방.

N^2 + 3N + 5 → N^2

점근적 표기법: 정확한 연산 횟수가 아닌, 연산 횟수의 추이 활용해 시간 복잡도 표기.

이 때 최악의 경우 고려하여 점근적 표기법으로 나타내는 것이 빅오표기법.

자주 보이는 복잡도의 점근적 표기법

  1. 1차원 배열 탐색: O(N)
  2. 2차원 배열 탐색: O(N*M)
  3. 이진탐색트리 원소 탐색: O(log N)
  4. 동전 N개를 던졌을 때 경우의 수: O(2^N)

점근적 표기법 코테에 활용하기

  1. 입력값의 크기를 통해 어느 정도 시간복잡도까지 허용되는지 추측 가능→ 본인이 구현한 코드가 시간 초과가 발생할지 미리 파악 가능
  2. → 대략 초당 1,000 ~ 2,000만 정도 연산한다 가정하면 된다.
  3. → 구현 시 알고리즘/자료구조 선택 명확히 할 수 있음

메서드의 시간 복잡도 파악

동일한 동작을 하는 것처럼 보이나 시간 복잡도가 다른 경우 존재

  1. 기본 컨테이너 - unordered 컨테이너
  2. vector와 dictionary/set에서 특정 key 존재 유무 확인
  3. vector와 list에서 특정 위치 원소 가져오기

실전 예시

문제 1 짝지어 제거하기

알파벳 소문자로 구성된 문자열에서 같은 알파벳이 2개 붙어 있는 짝을 찾습니다. 짝을 찾은 다음에는 그 둘을 제거한 뒤 앞뒤로 문자열을 이어붙입니다. 이 과정을 반복해서 문자열을 모두 제거한다면 짝지어 제거하기가 종료됩니다. 문자열 S가 주어졌을 때 짝지어 제거하기를 성공적으로 수행할 수 있는지 반환하는 함수를 완성하세요. 성공적으로 수행할 수 있으면 1, 아니면 0을 반환해주면 됩니다. 예를 들어 문자열 S가 baabaa라면

  • baabaa→ bbaa → aa

순서로 문자열을 모두 제거할 수 있으므로 1을 반환합니다.

제약 조건

문자열의 길이: 1,000,000 이하의 자연수

문자열은 모두 소문자로 이루어져 있음.