当前位置:首页 > JavaScript

js实现回溯法

2026-02-03 00:28:20JavaScript

回溯法概述

回溯法是一种通过递归或迭代探索所有可能解的算法,常用于解决组合、排列、子集等问题。其核心思想是“试错”:尝试某条路径,若发现不满足条件则回退(回溯),尝试其他路径。

回溯法的基本结构

回溯法通常包含以下步骤:

js实现回溯法

  1. 选择路径:从可选选项中做出一个选择。
  2. 递归探索:基于当前选择继续向下探索。
  3. 撤销选择:若当前路径不满足条件,回退到上一步状态。

通用代码框架:

function backtrack(路径, 选择列表) {
    if (满足结束条件) {
        结果.push(路径);
        return;
    }
    for (选择 of 选择列表) {
        做选择;
        backtrack(路径, 选择列表);
        撤销选择;
    }
}

经典问题示例

1. 全排列问题

给定不重复数字数组,返回所有可能的排列。

js实现回溯法

function permute(nums) {
    const res = [];
    const backtrack = (path, used) => {
        if (path.length === nums.length) {
            res.push([...path]);
            return;
        }
        for (let i = 0; i < nums.length; i++) {
            if (used[i]) continue;
            path.push(nums[i]);
            used[i] = true;
            backtrack(path, used);
            path.pop();
            used[i] = false;
        }
    };
    backtrack([], new Array(nums.length).fill(false));
    return res;
}

2. 子集问题

返回数组所有可能的子集。

function subsets(nums) {
    const res = [];
    const backtrack = (start, path) => {
        res.push([...path]);
        for (let i = start; i < nums.length; i++) {
            path.push(nums[i]);
            backtrack(i + 1, path);
            path.pop();
        }
    };
    backtrack(0, []);
    return res;
}

3. 组合总和

找出数组中总和为目标的组合(可重复使用数字)。

function combinationSum(candidates, target) {
    const res = [];
    const backtrack = (start, path, sum) => {
        if (sum === target) {
            res.push([...path]);
            return;
        }
        if (sum > target) return;
        for (let i = start; i < candidates.length; i++) {
            path.push(candidates[i]);
            backtrack(i, path, sum + candidates[i]);
            path.pop();
        }
    };
    backtrack(0, [], 0);
    return res;
}

优化技巧

  1. 剪枝:提前终止不符合条件的路径。例如在组合总和中,若当前和超过目标则直接返回。
  2. 去重:对输入数组排序,并在回溯时跳过重复元素(如 if (i > start && nums[i] === nums[i-1]) continue)。
  3. 记忆化:对于重叠子问题,缓存中间结果以减少重复计算。

注意事项

  • 递归深度过大可能导致栈溢出,需注意问题规模。
  • 在撤销选择时(如 path.pop()),需确保状态回退到上一步的准确值。

标签: js
分享给朋友:

相关文章

js实现图片上传

js实现图片上传

图片上传的基本实现 使用HTML的<input type="file">元素配合JavaScript的File API可以实现图片上传功能。HTML部分需要创建一个文件选择输入框和一个用于…

js实现图片放大缩小

js实现图片放大缩小

实现图片放大缩小的基础方法 使用CSS的transform: scale()属性可以快速实现图片的放大缩小效果。通过JavaScript动态修改该属性值: const img = document.…

js实现论坛

js实现论坛

实现论坛的基本功能 使用JavaScript实现一个论坛需要结合前端和后端技术。前端可以使用React、Vue或Angular等框架,后端可以选择Node.js配合Express或Koa框架。数据库可…

js类实现

js类实现

使用类实现 JavaScript 功能 在 JavaScript 中,类(Class)是一种语法糖,基于原型继承机制。通过 class 关键字可以更直观地定义对象模板。 基本类定义 class…

js图片轮播的实现

js图片轮播的实现

基础图片轮播实现 使用HTML、CSS和JavaScript实现一个简单的图片轮播效果。HTML部分定义轮播容器和图片,CSS负责样式和过渡效果,JavaScript处理逻辑。 <div cl…

js实现定位

js实现定位

使用Geolocation API获取当前位置 在JavaScript中,可以通过浏览器内置的Geolocation API获取用户的地理位置信息。该API需要用户授权才能访问位置数据。 if (n…