본문으로 바로가기
제품데스크톱 도구TASTECAD도면 확인TASTEFILES파일 관리TASTEFTP파일 전송TASTESSH원격 작업공간TASTEZIP압축과 해제개발 도구TASTECODERust 통합 개발 환경TASTESTUDIO통합 개발·테스트 환경TASTEETL데이터 통합(ETL)서버TASTEREMOTE원격 데스크톱 서버TASTEGEO공간정보 서버TASTEMAIL메일 작업공간시작하기다운로드문서구매모든 제품
마켓플레이스
소식
개발소식오늘의 개발 소식개발 문서프로그래밍 언어RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart프런트엔드 프레임워크Next.jsReactVue.js · NuxtSvelteKitAngular서버 프레임워크Spring BootDjangoFastAPIASP.NET CoreNestJS · Express앱 · 데스크톱 프레임워크TauriFlutterReact NativeElectron알고리즘알고리즘 기초알고리즘 핵심알고리즘 심화실무 알고리즘
커뮤니티프로젝트개발 로그프롬프트AI 도구 이슈쇼케이스커뮤니티 안내
협업기술 전수홈페이지 구축데스크톱 앱 구축릴리스·결제 파이프라인판매 파트너문의
서비스원격 데스크톱설치 패키지 커스텀
TASTEDEV
제품

데스크톱 도구

TASTECAD복잡한 도면을 가볍게 열다TASTEFILES필요한 파일만, 가장 빠르게TASTEFTP파일이 오가는 가장 단정한 길TASTESSH서버와 나 사이, 더 단단한 연결TASTEZIP더 빠르게 묶고, 더 안전하게 풀다

개발 도구

TASTECODERust 앱을 편집 · 빌드 · 디버깅 · 테스트까지 한 창에서TASTESTUDIO편집부터 원격 테스트와 승인 기반 AI 수정까지TASTEETL값을 보며 데이터를 옮깁니다

서버

TASTEREMOTE우리 회사 서버로 운영하는 원격 데스크톱TASTEGEOGeoServer 호환 공간정보 서버를 Rust로 다시 세웁니다TASTEMAIL메일의 주도권을 다시 내 손에

시작하기

다운로드모든 제품 최신 판문서제품 사용법구매구독 · 영구 라이선스모든 제품모든 제품 한눈에
모든 제품
마켓플레이스소식
개발

소식

오늘의 개발 소식언어 · 프레임워크 · GitHub · AI 공식 발표개발 문서언어 · 프레임워크 · 알고리즘 안내서

프로그래밍 언어

RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart

프레임워크

프런트엔드 프레임워크Next.jsReactVue.js · NuxtSvelteKitAngular
서버 프레임워크Spring BootDjangoFastAPIASP.NET CoreNestJS · Express
앱 · 데스크톱 프레임워크TauriFlutterReact NativeElectron

알고리즘

알고리즘 기초복잡도 분석 · 정렬 · 탐색 · 기본 자료구조 · 트리와 힙알고리즘 핵심그래프 탐색 · 최단 경로와 최소 신장 트리 · 동적 계획법 · 탐욕 알고리즘 · 분할 정복 · 백트래킹알고리즘 심화문자열 알고리즘 · 수학과 정수론 · 비트 연산 · 구간 트리 · 유니온 파인드실무 알고리즘코딩 면접 풀이 전략 · LRU 캐시 · 레이트 리미터 · 일관된 해시
개발 문서 전체 보기
커뮤니티
프로젝트빌더와 작업 발견개발 로그결정과 시행착오프롬프트재사용 가능한 지시AI 도구 이슈Claude · Codex · Gemini 문제와 우회법쇼케이스완성된 결과커뮤니티 안내공개하고 함께 만드는 방식
협업
기술 전수Rust·egui 네이티브 앱 만들기홈페이지 구축10개 언어, 계정, 문서·다운로드데스크톱 앱 구축Rust·egui, WebView 없이릴리스·결제 파이프라인서명 · MSI·deb·rpm·AppImage · 해시판매 파트너소개하고 결제액의 30% 받기문의구축 · 제휴 · 투자 문의
서비스
원격 데스크톱브라우저로 내 컴퓨터에 접속설치 패키지 커스텀필요한 기능만, 설정은 미리
구매
KO
한국어EnglishDeutschEspañolFrançaisItalianoPortuguês (Brasil)日本語简体中文繁體中文
로그인
로그인
TASTEDEV

작은 도구부터, 더 좋은 개발까지.

support@tastedev.netTASTEDEV 후원하기
제품제품군구매문서다운로드마켓플레이스고객 지원
커뮤니티프로젝트개발 로그프롬프트AI 도구 이슈쇼케이스
정책개인정보처리방침이용약관구독 약관환불 정책커뮤니티 운영 정책
계정로그인가입하기
방문자
오늘
012345678901234567890123456789012345678901234567890123456789
어제
012345678901234567890123456789012345678901234567890123456789
누적 조회
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
상호
지엑스소프트
대표자
최영구
사업자등록번호
853-44-00368
주소
인천광역시 미추홀구 경인로 351 9층 V24
전화
+82-10-4404-1523
이메일
whitecalvin@tastedev.net
개인정보 보호책임자
최영구

© 2026 TASTEDEV제품 정보는 현재 검증된 개발 소스를 기준으로 합니다.출시·고도화 중

복잡도 분석 문서
복잡도 분석
복잡도 분석의 개념동작 원리: 연산 세기에서 마스터 정리까지구현: 세 가지 차수를 직접 재 보기복잡도: 대표 차수, 상환 분석, 공간연습 문제실무 활용
토론

복잡도 분석 안내서 · 5/6

연습 문제

복잡도 분석은 많이 읽고 직접 세어 볼수록 빨라집니다. 아래 다섯 문제는 차수 읽기, 더 나은 차수로 고치기, 측정으로 확인하기를 차례로 연습하도록 구성했습니다. 먼저 스스로 풀어 본 다음 접근 방법과 풀이를 확인하세요.

문제 1. 차수 맞히기

다음 네 함수의 시간 복잡도를 구하세요. c의 result는 리스트입니다.

def a(n):
    total, i = 0, 1
    while i < n:
        for _ in range(n):
            total += 1
        i *= 2
    return total

def b(n):
    total = 0
    for _ in range(n):
        j = 1
        while j * j <= n:
            total += 1
            j += 1
    return total

def c(items):
    result = []
    for x in items:
        if x not in result:
            result.append(x)
    return result

def d(n):
    if n <= 1:
        return 1
    return d(n // 2) + d(n // 2)

접근: 바깥 반복과 안쪽 반복의 횟수를 따로 세어 곱합니다. 재귀는 점화식을 세웁니다.

  • a: 바깥은 i가 두 배씩 커지므로 약 log n번, 안쪽은 n번입니다. O(n log n)
  • b: 안쪽은 j ≤ √n까지 돌므로 O(n√n), 즉 O(n^1.5)
  • c: x not in result가 리스트를 훑습니다. 모든 값이 다르면 0 + 1 + ... + (n-1)번 비교하므로 O(n²). 집합을 함께 쓰면 O(n)이 됩니다.
  • d: T(n) = 2T(n/2) + O(1)이라 log n처럼 보이지만, 마스터 정리로 O(n)입니다. 호출 수를 세어 확인할 수 있습니다.
calls = 0

def d_counted(n):
    global calls
    calls += 1
    if n <= 1:
        return 1
    return d_counted(n // 2) + d_counted(n // 2)

for n in (1_024, 2_048, 4_096):
    calls = 0
    d_counted(n)
    print(n, calls)   # 2047, 4095, 8191: n이 2배면 호출도 2배

문제 2. 처음 반복되는 값

리스트에서 두 번째로 나타나는 순간이 가장 이른 값을 돌려주세요. 없으면 None입니다. 예: [4, 7, 1, 7, 4]에서는 7이 먼저 두 번 나타나므로 답은 7입니다.

접근: 모든 쌍을 보면 O(n²)입니다. 앞에서부터 훑으며 본 값을 집합에 넣으면, 집합 조회가 평균 O(1)이므로 전체 O(n) 시간, O(n) 공간입니다.

def first_repeat(items):
    seen = set()
    for x in items:
        if x in seen:
            return x
        seen.add(x)
    return None

print(first_repeat([4, 7, 1, 7, 4]))  # 7
print(first_repeat([1, 2, 3]))        # None

메모리를 아껴야 하고 "중복이 있는가"만 알면 된다면, 정렬한 뒤 이웃끼리 비교하는 O(n log n) 시간 방법도 있습니다. 시간과 공간 중 무엇이 귀한지에 따라 고릅니다.

문제 3. 차이가 k인 쌍

오름차순으로 정렬된 정수 리스트와 0 이상의 정수 k가 주어질 때, 두 원소의 차가 정확히 k인 쌍이 있는지 판단하세요. O(n)으로 풀어야 합니다.

접근: 두 포인터 i < j를 둡니다. 차가 k보다 작으면 j를 늘려 차를 키우고, 크면 i를 늘려 차를 줄입니다. 두 포인터가 각각 최대 n번만 움직이므로 O(n)입니다.

def has_pair_with_difference(nums, k):
    i, j = 0, 1
    while j < len(nums):
        if i == j:
            j += 1
            continue
        diff = nums[j] - nums[i]
        if diff == k:
            return True
        if diff < k:
            j += 1
        else:
            i += 1
    return False

print(has_pair_with_difference([1, 3, 6, 10, 15], 4))  # True (6, 10)
print(has_pair_with_difference([1, 3, 6, 10, 15], 2))  # True (1, 3)
print(has_pair_with_difference([1, 3, 6, 10, 15], 8))  # False

문제 4. 구간 합 질의

길이 n인 리스트와 q개의 질의 (l, r)이 주어집니다. 각 질의마다 nums[l:r]의 합을 구하세요.

접근: 질의마다 sum(nums[l:r])을 하면 O(n·q)입니다. 누적 합 prefix[i] = nums[0] + ... + nums[i-1]을 한 번 만들어 두면 질의 하나가 뺄셈 한 번이 되어 전체 O(n + q)입니다.

from itertools import accumulate

def range_sums(nums, queries):
    prefix = [0, *accumulate(nums)]
    return [prefix[r] - prefix[l] for l, r in queries]

print(range_sums([3, 1, 4, 1, 5, 9], [(0, 3), (2, 6), (5, 6)]))  # [8, 19, 9]

문제 5. 측정으로 차수 추정하기

함수와 입력 생성 함수를 받아, n과 2n에서 걸린 시간의 비율로 차수의 지수를 추정하세요.

접근: T(n) ≈ c·n^k라면 T(2n) / T(n) ≈ 2^k이므로 k ≈ log₂(T(2n) / T(n))입니다. 잡음을 줄이려고 timeit.repeat의 최솟값을 씁니다.

import math
import timeit

def estimate_exponent(func, make_input, n, number=3):
    def best_time(size):
        data = make_input(size)
        return min(timeit.repeat(lambda: func(data), number=number, repeat=5))
    return math.log2(best_time(2 * n) / best_time(n))

def all_pairs(items):
    return sum(1 for i in range(len(items)) for j in range(i + 1, len(items)))

print(round(estimate_exponent(sum, lambda n: list(range(n)), 200_000), 1))   # 약 1
print(round(estimate_exponent(all_pairs, lambda n: list(range(n)), 1_000), 1))  # 약 2

정리

  • 반복 횟수를 곱하고, 숨은 in list 비용과 재귀 점화식을 놓치지 않는 것이 차수 읽기의 핵심입니다.
  • 집합, 두 포인터, 누적 합은 O(n²) 또는 O(n·q)를 선형으로 줄이는 대표 도구입니다.
  • 이론으로 구한 차수는 두 배 실험으로 확인하는 습관을 들이면 좋습니다.
이 장에 대해 질문이 있나요?
이전 장복잡도: 대표 차수, 상환 분석, 공간다음 장실무 활용

댓글 0개

인기 댓글순최신순

로그인 · 로그인하면 댓글을 남길 수 있습니다.