본문으로 바로가기
제품데스크톱 도구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: 합이 정확히 k인 구간 개수 (누적 합 + 해시 맵)

하루 단위 수입과 지출이 정수 배열 amounts로 주어집니다(음수 포함). 연속된 날들의 합이 정확히 k가 되는 구간의 개수를 구하세요.

예: amounts = [1, 2, -1, 2, 1], k = 3이면 [1, 2], [2, -1, 2], [2, 1]로 답은 3입니다.

접근: 음수가 있으므로 슬라이딩 윈도우가 통하지 않습니다. 앞에서부터의 누적 합을 p라 하면, 구간 합이 k인 것은 p[j] - p[i] = k, 즉 지금 누적 합에서 k를 뺀 값이 이전에 몇 번 나왔는지와 같습니다. 누적 합의 등장 횟수를 해시 맵에 세면 됩니다. 빈 접두사를 나타내는 0을 처음에 한 번 넣어 두는 것이 핵심입니다.

from collections import defaultdict


def count_sum_k(amounts: list[int], k: int) -> int:
    seen = defaultdict(int)
    seen[0] = 1           # 아무것도 더하지 않은 상태
    prefix = count = 0
    for x in amounts:
        prefix += x
        count += seen[prefix - k]
        seen[prefix] += 1
    return count


print(count_sum_k([1, 2, -1, 2, 1], 3))  # 3
print(count_sum_k([0, 0], 0))            # 3

복잡도: 시간 O(n), 공간 O(n).

문제 2: 합이 target 이하인 쌍의 개수 (투 포인터)

오름차순으로 정렬된 정수 배열 nums가 있습니다. i < j이고 nums[i] + nums[j] <= target인 쌍의 개수를 구하세요.

예: nums = [1, 2, 3, 4, 6], target = 6이면 (1, 2), (1, 3), (1, 4), (2, 3), (2, 4)로 답은 5입니다.

접근: 양 끝에 포인터를 둡니다. nums[lo] + nums[hi] <= target이면 lo와 짝지을 수 있는 원소가 lo + 1부터 hi까지 모두이므로 hi - lo개를 한꺼번에 세고 lo를 늘립니다. 그렇지 않으면 hi를 줄입니다.

def count_pairs_at_most(nums: list[int], target: int) -> int:
    lo, hi = 0, len(nums) - 1
    count = 0
    while lo < hi:
        if nums[lo] + nums[hi] <= target:
            count += hi - lo
            lo += 1
        else:
            hi -= 1
    return count


print(count_pairs_at_most([1, 2, 3, 4, 6], 6))  # 5
print(count_pairs_at_most([5, 5, 5], 9))        # 0

복잡도: 시간 O(n)(정렬되지 않았다면 정렬 포함 O(n log n)), 공간 O(1).

문제 3: 서로 다른 값이 k개 이하인 가장 긴 구간 (슬라이딩 윈도우 + 해시 맵)

접속 기록이 사용자 ID 배열 log로 주어집니다. 서로 다른 ID가 최대 k개만 들어 있는 가장 긴 연속 구간의 길이를 구하세요.

예: log = ["a", "b", "a", "c", "c", "c"], k = 2이면 ["a", "c", "c", "c"]의 길이 4가 답입니다.

접근: 창 안의 ID별 개수를 해시 맵에 둡니다. 오른쪽에서 하나를 넣은 뒤 서로 다른 ID가 k개를 넘으면, 넘지 않을 때까지 왼쪽에서 빼고 개수가 0이 된 ID는 맵에서 지웁니다. 맵의 크기가 곧 서로 다른 ID의 수입니다.

from collections import Counter


def longest_at_most_k_distinct(log: list[str], k: int) -> int:
    counts: Counter[str] = Counter()
    left = best = 0
    for right, user in enumerate(log):
        counts[user] += 1
        while len(counts) > k:
            counts[log[left]] -= 1
            if counts[log[left]] == 0:
                del counts[log[left]]
            left += 1
        best = max(best, right - left + 1)
    return best


print(longest_at_most_k_distinct(["a", "b", "a", "c", "c", "c"], 2))  # 4
print(longest_at_most_k_distinct(["x", "y"], 0))                      # 0

복잡도: 시간 O(n), 공간 O(k).

문제 4: 딱 한 번 나온 첫 ID (해시 맵으로 개수 세기)

이벤트 ID 배열에서 전체에 정확히 한 번만 나온 ID 가운데 가장 먼저 나온 것을 찾으세요. 없으면 None을 돌려줍니다.

예: ["k", "m", "k", "p", "m"]이면 답은 "p"입니다.

접근: 첫 번째 훑기에서 개수를 세고, 두 번째 훑기에서 원래 순서대로 개수가 1인 첫 값을 찾습니다. 두 번 훑어도 시간은 O(n)입니다.

from collections import Counter


def first_unique(events: list[str]) -> str | None:
    counts = Counter(events)
    for event in events:
        if counts[event] == 1:
            return event
    return None


print(first_unique(["k", "m", "k", "p", "m"]))  # p
print(first_unique(["k", "k"]))                 # None

문제 5: 정렬된 배열에서 값의 등장 횟수 (이분 탐색)

정렬된 배열 nums에서 값 x가 몇 번 나오는지 O(log n)에 구하세요.

접근: x 이상인 첫 위치와 x보다 큰 첫 위치의 차이가 등장 횟수입니다. 표준 라이브러리 bisect가 두 위치를 바로 알려 줍니다. 면접에서 직접 구현을 요구하면 아래처럼 lower_bound를 써 보입니다.

from bisect import bisect_left, bisect_right


def lower_bound(nums: list[int], x: int) -> int:
    lo, hi = 0, len(nums)            # 답은 [lo, hi] 안에 있다
    while lo < hi:
        mid = (lo + hi) // 2
        if nums[mid] < x:
            lo = mid + 1
        else:
            hi = mid
    return lo


nums = [1, 2, 2, 2, 5, 7]
print(bisect_right(nums, 2) - bisect_left(nums, 2))  # 3
print(lower_bound(nums, 2), lower_bound(nums, 6))    # 1 5

정리

다섯 문제는 각각 누적 합, 투 포인터, 가변 슬라이딩 윈도우, 개수 세기, 이분 탐색을 연습합니다. 풀이를 외우기보다 "음수가 있으니 윈도우가 안 된다", "정렬되어 있으니 양 끝에서 좁힌다"처럼 패턴을 고른 이유를 말로 설명할 수 있는지 확인하세요. 같은 문제를 다른 언어로 다시 풀어 보는 것도 좋은 복습이 됩니다.

이 장에 대해 질문이 있나요?
이전 장복잡도 설명과 트레이드오프다음 장실전 준비와 시험 환경

댓글 0개

인기 댓글순최신순

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