首页 > 编程语言 >【唐叔学算法】第12天:回溯算法-探索所有可能的旅程

【唐叔学算法】第12天:回溯算法-探索所有可能的旅程

时间:2024-12-10 22:27:31浏览次数:6  
标签:12 nums 唐叔学 List 算法 result 回溯 tempList

在算法的世界中,回溯算法是一种通过试错来解决问题的方法。它尝试分步解决一个问题,如果在某个步骤中发现之前的选择并不会导致一个有效的解决方案,它将取消上一步甚至是上几步的选择,回退到之前的状态,再尝试另一种可能的解决方案。作为一名Java技术博主,我将带你深入了解回溯算法的工作原理,探索其在解决实际问题中的应用。通过本文,你将学会如何运用回溯算法来处理各种复杂问题,并在LeetCode上的应用实例中,掌握其解题技巧。

PS:DFS是一种遍历策略,而回溯算法是一种通用的求解方法,它可以利用DFS来进行状态空间树的探索。因此,可以说回溯算法在实现过程中可能会使用DFS,但这并不意味着它们是相同的。有关DFS的介绍,可以参考上一篇文章。【唐叔学算法】第11天:深度优先遍历-探索图与树的神秘深处

一、什么是回溯算法?

定义

回溯算法是一种系统性搜索问题解空间的方法,它类似于暴力求解,但更加智能。当面对一个问题时,我们会逐步构建解决方案,并在每一步都做出选择。如果发现当前选择无法通向正确答案,则撤销该选择(即“回溯”),并尝试其他可能性。

应用场景

回溯算法广泛应用于以下场景:

  • 排列与组合:如生成所有可能的数字或字母组合。
  • 棋盘问题:例如八皇后问题。
  • 迷宫求解:寻找从起点到终点的所有路径。
  • 约束满足问题:如数独游戏。
  • 搜索问题:寻找满足特定条件的解空间。

算法实现

回溯算法的核心在于递归函数的设计。每个递归调用代表一次新的尝试,其中包含了以下三个关键步骤:

  1. 做选择:在当前节点处选择一个分支进行探索。
  2. 递归调用:基于所做的选择继续向下一层递归。
  3. 撤销选择:一旦发现这条路径不通或者已经找到解,则回退至上一级状态,尝试其他选择。

注意事项

  • 剪枝优化:尽可能早地识别出不可能成功的路径,以减少不必要的计算。
  • 边界条件:确保递归终止条件准确无误,避免无限递归。
  • 性能考量:对于大规模数据集,考虑使用更高效的算法或数据结构。

二、实战解析

入门题:78. 子集

题目链接:78. 子集
题目描述:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

解题思路

这个问题可以通过回溯算法来解决。我们从空集开始,逐个添加元素形成新的子集,直到包含所有原始元素为止。每次添加新元素后,都将当前形成的子集加入结果集中。

Java代码实现
import java.util.*;

public class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        backtrack(result, new ArrayList<>(), nums, 0);
        return result;
    }

    private void backtrack(List<List<Integer>> result, List<Integer> tempList, int[] nums, int start) {
        result.add(new ArrayList<>(tempList));
        for (int i = start; i < nums.length; ++i) {
            tempList.add(nums[i]);
            backtrack(result, tempList, nums, i + 1);
            tempList.remove(tempList.size() - 1); // 撤销选择
        }
    }
}

中等题:46. 全排列

题目链接:46. 全排列
题目描述:给定一个没有重复数字的序列 nums,返回其所有可能的全排列。

解题思路

此题同样适用回溯算法解决。我们需要为每个位置挑选一个尚未使用的数字作为候选者,然后递归处理剩余的位置,直至完成整个排列。

Java代码实现
import java.util.*;

public class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        boolean[] used = new boolean[nums.length];
        backtrack(result, new ArrayList<>(), nums, used);
        return result;
    }

    private void backtrack(List<List<Integer>> result, List<Integer> tempList, int[] nums, boolean[] used) {
        if (tempList.size() == nums.length) {
            result.add(new ArrayList<>(tempList));
        } else {
            for (int i = 0; i < nums.length; ++i) {
                if (used[i]) continue;
                used[i] = true;
                tempList.add(nums[i]);
                backtrack(result, tempList, nums, used);
                used[i] = false;
                tempList.remove(tempList.size() - 1); // 撤销选择
            }
        }
    }
}

三、更多LeetCode题目推荐

如果您对回溯算法感兴趣,希望挑战更多题目,以下是一些LeetCode上推荐的题目:

四、总结

回溯算法以其在解决组合、排列和分割问题中的独特能力,成为算法设计中的重要工具。如果你有任何问题或想法,欢迎在评论区与我交流。让我们一起享受编程的乐趣,不断探索和学习!


如果你喜欢这篇文章,不妨点赞、收藏或转发给你的朋友们哦!也欢迎关注我的微信公众号【唐叔在学习】,获取更多技术文章和学习资料。我是唐叔,我们下次再见!

标签:12,nums,唐叔学,List,算法,result,回溯,tempList
From: https://blog.csdn.net/Tang_is_learning/article/details/144385439

相关文章

  • 算法--排序算法
    选择排序#选择排序#选择排序思路:#-每次从[i,n-1]区间中选择最小值,放到i位置上#-i取值为[0,n-1],因为如果最后只有一个数,则无需查询,i取值为[0,n-2]即可defselect_sort(nums:list[int]):n=len(nums)ifn<=1:returnforiinr......
  • 【推荐算法】单目标精排模型——FiBiNET
    keyword:学术论文Motivation:传统的Embedding&MLP算法是通过内积和Hadamardproduct实现特征交互的,这篇文章的作者提出了采用SENET实现动态学习特征的重要性;作者认为简单的内积和Hadamardproduct无法有效对稀疏特征进行特征交互,因此提出bilinearfunction实现特征交互,提出了FI......
  • 力扣-图论-8【算法学习day.58】
    前言###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程(例如想要掌握基础用法,该刷哪些题?)我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴!!!习题1.引爆最多的炸弹题目链接:2101.引爆最多的炸弹-力扣(Le......
  • C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
    前言C#/.NET/.NETCore技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NETCore领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。欢迎投稿、推荐或自荐优质文章、项目、学习资源等。......
  • JS-12 条件语句之if语句
    if结构先判断一个表达式的布尔值,然后根据布尔值的真伪,执行不同的语句。所谓布尔值,指的是JavaScript的两个特殊值,true表示真,false表示伪。布尔表达式→true→语句块→布尔表达式→false(跳过语句块)→1、if语句语法规范if(布尔值){语句;}  ......
  • 高级java每日一道面试题-2024年12月10日-并发篇-为什么不建议通过 Executors构建线程
    如果有遗漏,评论区告诉我进行补充面试官:为什么不建议通过Executors构建线程池?我回答:在Java高级面试中,面试官可能会问到为什么不建议通过Executors构建线程池,这是一个关于线程池配置、资源管理和性能优化的重要问题。以下是对这一问题的详细解答:一、Executors的默认......
  • 124. 二叉树中的最大路径和
    问题描述二叉树中的路径被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中至多出现一次。该路径至少包含一个节点,且不一定经过根节点。路径和是路径中各节点值的总和。给你一个二叉树的根节点root,返回其最大路径和。分析树形D......
  • 二叉搜索树深度解析:三个关键算法(235,669,108)
    ......
  • THUPC 2024初赛 组队VP 2024.12.7
    组队的思路不会写太清楚,这个只供日后队内需要进行查看C.前缀和题面:小兰喜欢随机数,TA首先选定了一个实数\(0<p<1\),然后生成了\(n\)个随机数\(x_1,\ldots,x_n\),每个数是独立按照如下方式生成的:\(x_i\)有\(p\)的概率是1,有\((1-p)p\)的概率是2,有\((1-p)^2p\)......
  • 2024/12/10
    昨天收盘后12月份的中央政治局会议,内容出来后,“适度宽松的货币政策”,是属于09后第一次提出,市场反馈很好,A50期指和港股大涨,网上几乎所有的主播都在看多,都人认为牛来了,千万网名都在摩拳擦掌跃跃欲试,期待第二天的开盘,这是一个不眠之夜!今天大A果然高开,集合竞价的时候证券等多个版块涨......