본문으로 바로가기
제품데스크톱 도구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제품 정보는 현재 검증된 개발 소스를 기준으로 합니다.출시·고도화 중

백트래킹 문서
백트래킹
백트래킹의 개념동작 원리구현복잡도연습 문제실무 활용
토론

백트래킹 안내서 · 3/6

구현

이 장에서는 Python으로 부분집합, 순열, N-Queens를 구현하고 한 줄씩 설명합니다. 이어서 N-Queens 해의 개수를 세는 같은 핵심 루틴을 C++, Java, TypeScript로 옮깁니다. 언어가 달라도 구조는 선택, 탐색, 되돌리기 세 줄로 똑같습니다.

부분집합과 순열 (Python)

def subsets(nums):
    result, path = [], []

    def dfs(start):
        result.append(path[:])            # 모든 노드가 하나의 부분집합
        for i in range(start, len(nums)):
            path.append(nums[i])          # 선택
            dfs(i + 1)                    # 탐색: i 뒤만 고른다
            path.pop()                    # 되돌리기

    dfs(0)
    return result


def permutations(nums):
    result, path = [], []
    used = [False] * len(nums)

    def dfs():
        if len(path) == len(nums):        # 리프: 순열 하나 완성
            result.append(path[:])
            return
        for i, x in enumerate(nums):
            if used[i]:                   # 이미 쓴 원소는 건너뜀
                continue
            used[i] = True
            path.append(x)
            dfs()
            path.pop()
            used[i] = False

    dfs()
    return result
  • subsets는 리프가 아니라 모든 노드에서 결과를 저장합니다. start부터만 고르기 때문에 [1, 2]와 [2, 1]이 둘 다 생기지 않습니다.
  • permutations는 순서가 중요하므로 매번 처음부터 훑되, used 배열로 이미 고른 원소를 막습니다. used[i] = False가 되돌리기의 짝입니다.
  • 두 함수 모두 path[:]로 복사해 저장합니다.

N-Queens (Python)

def solve_n_queens(n):
    cols, diag, anti = set(), set(), set()
    queens, boards = [], []

    def place(row):
        if row == n:                                   # 모든 행에 놓음
            boards.append(["." * c + "Q" + "." * (n - c - 1) for c in queens])
            return
        for c in range(n):
            if c in cols or row - c in diag or row + c in anti:
                continue                               # 가지치기
            cols.add(c); diag.add(row - c); anti.add(row + c)
            queens.append(c)
            place(row + 1)
            queens.pop()
            cols.remove(c); diag.remove(row - c); anti.remove(row + c)

    place(0)
    return boards

for line in solve_n_queens(4)[0]:
    print(line)
# .Q..
# ...Q
# Q...
# ..Q.
  • 한 행에 퀸을 하나씩 놓으므로 row가 깊이입니다.
  • cols, diag(row - c), anti(row + c) 세 집합으로 충돌 검사를 O(1)에 끝냅니다. 앞 장의 is_safe처럼 매번 모든 퀸을 훑으면 O(n)이 듭니다.
  • 선택할 때 세 집합에 넣고, 돌아올 때 같은 값을 빼야 다른 가지가 깨끗한 상태에서 시작합니다.

N-Queens 해의 개수 (C++)

다른 언어에서는 해를 세기만 하는 같은 루틴을 보여 줍니다. 열과 대각선 번호가 작은 정수이므로 집합 대신 불리언 배열을 씁니다.

#include <iostream>
#include <vector>

int n;
std::vector<bool> col, diag, anti;

int place(int row) {
    if (row == n) return 1;
    int count = 0;
    for (int c = 0; c < n; ++c) {
        if (col[c] || diag[row - c + n - 1] || anti[row + c]) continue;
        col[c] = diag[row - c + n - 1] = anti[row + c] = true;
        count += place(row + 1);
        col[c] = diag[row - c + n - 1] = anti[row + c] = false;
    }
    return count;
}

int main() {
    n = 8;
    col.assign(n, false);
    diag.assign(2 * n - 1, false);
    anti.assign(2 * n - 1, false);
    std::cout << place(0) << "\n";  // 92
}

row - c는 음수가 될 수 있으므로 n - 1을 더해 0부터 2n - 2까지의 배열 인덱스로 바꿉니다.

N-Queens 해의 개수 (Java)

public class NQueens {
    static int n;
    static boolean[] col, diag, anti;

    static int place(int row) {
        if (row == n) return 1;
        int count = 0;
        for (int c = 0; c < n; c++) {
            if (col[c] || diag[row - c + n - 1] || anti[row + c]) continue;
            col[c] = diag[row - c + n - 1] = anti[row + c] = true;
            count += place(row + 1);
            col[c] = diag[row - c + n - 1] = anti[row + c] = false;
        }
        return count;
    }

    public static void main(String[] args) {
        n = 8;
        col = new boolean[n];
        diag = new boolean[2 * n - 1];
        anti = new boolean[2 * n - 1];
        System.out.println(place(0)); // 92
    }
}

N-Queens 해의 개수 (TypeScript)

function countNQueens(n: number): number {
  const col = new Array<boolean>(n).fill(false);
  const diag = new Array<boolean>(2 * n - 1).fill(false);
  const anti = new Array<boolean>(2 * n - 1).fill(false);

  const place = (row: number): number => {
    if (row === n) return 1;
    let count = 0;
    for (let c = 0; c < n; c++) {
      const d = row - c + n - 1;
      if (col[c] || diag[d] || anti[row + c]) continue;
      col[c] = diag[d] = anti[row + c] = true;
      count += place(row + 1);
      col[c] = diag[d] = anti[row + c] = false;
    }
    return count;
  };

  return place(0);
}

console.log(countNQueens(8)); // 92

정리

  • 부분집합은 모든 노드에서, 순열과 N-Queens는 리프에서 결과를 저장합니다.
  • 충돌 검사를 집합이나 배열로 바꾸면 한 번의 검사가 O(1)이 됩니다.
  • 선택할 때 바꾼 상태는 돌아올 때 정확히 같은 순서로 되돌려야 합니다.
이 장에 대해 질문이 있나요?
이전 장동작 원리다음 장복잡도

댓글 0개

인기 댓글순최신순

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