跳到正文
产品桌面工具TASTECAD图纸查看TASTEFILES文件管理TASTEFTP文件传输TASTESSH远程工作空间TASTEZIP压缩与解压开发工具TASTECODERust 集成开发环境TASTESTUDIO集成开发与测试环境TASTEETL数据整合(ETL)服务器TASTEREMOTE远程桌面服务器TASTEGEO空间信息服务器TASTEMAIL邮件工作空间开始使用下载文档购买全部产品
市场
资讯
技术资讯今日开发资讯开发文档编程语言RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDartWeb 前端框架Next.jsReactVue.js · NuxtSvelteKitAngular服务端框架Spring BootDjangoFastAPIASP.NET CoreNestJS · Express应用与桌面框架TauriFlutterReact NativeElectron算法算法基础核心算法进阶算法实用算法
社区项目开发日志提示词AI 工具问题作品展示社区指南
合作技术传授网站构建桌面应用构建发布与支付流水线销售合作伙伴联系我们
服务远程桌面安装包定制
TASTEDEV
产品

桌面工具

TASTECAD复杂图纸,轻松打开TASTEFILES只要需要的文件,最快送达TASTEFTP让文件往来,干净利落TASTESSH你与服务器之间,连接更牢靠TASTEZIP压得更快,解得更稳

开发工具

TASTECODE在一个窗口中完成 Rust 应用的编辑、构建、调试和测试TASTESTUDIO从编辑到远程测试,再到经批准的 AI 修复TASTEETL边看数值,边搬数据

服务器

TASTEREMOTE在自己的服务器上运行的远程桌面TASTEGEO用 Rust 重新构建兼容 GeoServer 的空间信息服务器TASTEMAIL把邮件的主导权拿回自己手中

开始使用

下载所有产品的最新版本文档各产品使用方法购买订阅与永久许可全部产品一览全部产品
全部产品
市场资讯
技术

资讯

今日开发资讯语言、框架、GitHub 与 AI 官方发布开发文档语言、框架与算法指南

编程语言

RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart

框架

Web 前端框架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%联系我们开发、合作与投资咨询
服务
远程桌面用浏览器连接你的电脑安装包定制只装需要的,设置预先放好
购买
ZH
한국어EnglishDeutschEspañolFrançaisItalianoPortuguês (Brasil)日本語简体中文繁體中文
登录
登录
TASTEDEV

从小工具到更好的开发。

support@tastedev.net支持 TASTEDEV
产品产品线购买文档下载市场客户支持
社区项目开发日志提示词AI 工具问题作品展示
政策隐私政策服务条款订阅条款退款政策社区规范
账户登录注册
访客
今天
012345678901234567890123456789012345678901234567890123456789
昨天
012345678901234567890123456789012345678901234567890123456789
累计浏览
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
公司名称
GXSOFT
法定代表人
CHOI YOUNG GU
营业执照号
853-44-00368
地址
9F V24, 351 Gyeongin-ro, Michuhol-gu, Incheon, Republic of Korea
电话
+82-10-4404-1523
电子邮件
whitecalvin@tastedev.net
个人信息保护负责人
CHOI YOUNG GU

© 2026 TASTEDEV产品信息以已验证的开发源码为准。已发布·持续改进

回溯法 文档
回溯法
Backtracking ConceptsHow It WorksImplementationComplexityPractice ProblemsBacktracking in the Real World
讨论

回溯法 指南 · 3/6

Implementation

本章目前仅提供英文版。

This chapter implements subsets, permutations, and N-Queens in Python and walks through them line by line. Then it ports the same core routine, counting N-Queens solutions, to C++, Java, and TypeScript. Whatever the language, the structure is the same three lines: choose, explore, unchoose.

Subsets and permutations (Python)

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

    def dfs(start):
        result.append(path[:])            # every node is a subset
        for i in range(start, len(nums)):
            path.append(nums[i])          # choose
            dfs(i + 1)                    # explore: only pick after i
            path.pop()                    # unchoose

    dfs(0)
    return result


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

    def dfs():
        if len(path) == len(nums):        # leaf: one full permutation
            result.append(path[:])
            return
        for i, x in enumerate(nums):
            if used[i]:                   # skip elements already taken
                continue
            used[i] = True
            path.append(x)
            dfs()
            path.pop()
            used[i] = False

    dfs()
    return result
  • subsets records a result at every node, not just at leaves. Because it only picks from start onward, [1, 2] and [2, 1] are never both produced.
  • permutations cares about order, so it scans from the beginning every time and uses the used array to block elements already chosen. used[i] = False is the matching undo.
  • Both functions store a copy with path[:].

N-Queens (Python)

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

    def place(row):
        if row == n:                                   # every row filled
            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                               # prune
            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.
  • One queen goes in each row, so row is the depth of the tree.
  • Three sets, cols, diag (row - c), and anti (row + c), make each conflict check O(1). Scanning every queen, as is_safe did in the previous chapter, costs per check.
对本章有疑问?
上一章How It Works下一章Complexity
O(n)
  • Values added to the sets when choosing must be removed when returning, so the next branch starts from a clean state.
  • Counting N-Queens solutions (C++)

    The other languages show the same routine, counting solutions only. Column and diagonal numbers are small integers, so boolean arrays replace the sets.

    #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
    }

    Since row - c can be negative, adding n - 1 maps it onto array indices from 0 to 2n - 2.

    Counting N-Queens solutions (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
        }
    }

    Counting N-Queens solutions (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

    Summary

    • Subsets are recorded at every node; permutations and N-Queens are recorded at leaves.
    • Turning conflict checks into set or array lookups makes each check O(1).
    • Whatever state you change when choosing must be restored, in the same way, when you return.

    0 条评论

    热门评论最新优先

    登录 · 登录后即可发表评论。