搜索回溯算法

本文详细介绍了搜索回溯算法,包括其工作原理(候选解、选择、剪枝、回溯和目标测试),并通过LeetCode的39题(组合总和)实例演示如何使用搜索二叉树实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

搜索回溯算法是一种通过探索所有可能的候选解来找出所有解的算法。它采用深度优先搜索策略,尝试分步地去解决问题。在搜索过程中,当通过一系列的选择到达某个状态时,如果确定该状态不可能是最终解(或者不可能达到最终解),则“回溯”到上一步,尝试其他的选择。

原理:
1.候选解:从根节点(初始状态)出发,搜索解空间树。树中的每个节点代表一个候选解。
2.选择:在搜索树的当前节点,根据问题的约束条件,选择下一个扩展节点。
3.剪枝:如果确定当前候选解不可能成为最终解,则停止对该候选解所在子树的进一步搜索。
4.回溯:当从当前候选解不能得到最终解时,返回其前驱节点,并换一条路走。
5.目标测试:当达到某个节点时,判断该节点是否满足问题的目标条件,如果满足则将其加入到解集中。

通用步骤的伪代码:

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

举例:
leetcode39
在这里插入图片描述
在这里插入图片描述
解题的思路和理解,利用搜索二叉树这样一个虚拟的结构,对于原数组来说,按照顺序可以依次选择需不需要,如果需要,添加到目标数组,那么target就要减去该元素,但是要注意回溯,需要再把该元素remove了。

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> combine = new ArrayList<Integer>();
        dfs(candidates, target, ans, combine, 0);
        return ans;
    }

    public void dfs(int[] candidates, int target, List<List<Integer>> ans, List<Integer> combine, int idx) {
        if (idx == candidates.length) {
            return;
        }
        if (target == 0) {
            ans.add(new ArrayList<Integer>(combine));
            return;
        }
        // 直接跳过
        dfs(candidates, target, ans, combine, idx + 1);
        // 选择当前数
        if (target - candidates[idx] >= 0) {
            combine.add(candidates[idx]);
            dfs(candidates, target - candidates[idx], ans, combine, idx);
            combine.remove(combine.size() - 1);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@业精于勤荒于嬉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值