Java回溯算法知识点(含面试大厂题和源码)

回溯算法是一种通过试错来解决问题的算法,它尝试分步解决一个问题。如果发现当前的步骤不能得到有效的解决方案,它将取消上一步或几步的计算,再尝试其他的解决方案。回溯算法通常用递归方法实现,适用于解决组合问题、划分问题、排列问题、子集问题等。

回溯算法的关键知识点:

  1. 递归思想
    回溯算法通常使用递归函数来实现。递归函数在每次调用时,都会尝试一种可能的解决方案,如果这种解决方案不可行,就会回退到上一步,尝试其他的解决方案。

  2. 三种基本框架
    回溯算法的实现通常有三种基本框架:

    • 深度优先搜索(DFS):从起点开始,尽可能深地搜索树的分支。
    • 广度优先搜索(BFS):从起点开始,先搜索树的所有第一层的节点,再逐层深入。
    • 迭代回溯:使用栈来模拟递归过程,避免递归带来的额外开销。
  3. 剪枝操作
    在回溯过程中,剪枝是非常重要的优化操作。它指的是在搜索过程中,提前排除那些明显不会得到解的情况,从而减少不必要的计算。

  4. 约束条件和目标函数
    回溯算法在解决问题时,需要定义约束条件和目标函数。约束条件用于判断当前的解决方案是否可行,目标函数用于评估当前解决方案的优劣。

  5. 记忆化搜索
    记忆化搜索是一种优化技术,它将已经解决的子问题的答案存储起来,当需要再次解决同一个子问题时,可以直接查找答案,避免重复计算。

  6. 回溯算法的应用
    回溯算法广泛应用于解决组合问题、划分问题、排列问题、子集问题等。例如八皇后问题、图的着色问题、旅行商问题、0-1背包问题等。

实现回溯算法的步骤:

  1. 确定解空间:首先需要确定问题的解空间,即所有可能的解决方案。

  2. 探索解空间:使用递归或迭代的方式,逐步探索解空间中的每一个可能的解。

  3. 约束条件检查:在探索过程中,使用约束条件来过滤掉不符合条件的解。

  4. 回溯:当探索到当前路径无法得到有效解时,回退到上一步,尝试其他的解决方案。

  5. 记录和输出解:当找到一个可行解时,记录下来。如果需要找到所有解,则继续探索;如果只需要找到一个解,则输出当前解并结束。

回溯算法是一种强大而又灵活的算法,通过不断的尝试和错误,最终找到问题的解。掌握回溯算法,可以帮助你在面试中解决各种复杂的问题。

题目 1:N 皇后问题

问题描述:在 N×N 的棋盘上摆放 N 个皇后,使得它们不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。求解所有可能的摆放方案。

Java 源码

public class NQueens {
    static int count = 0; // 用于记录解的个数

    public static void placeQueen(int n, int[][] board) {
        if (placeQueenHelper(n, board, 0)) {
            printSolution(board);
            count++;
        }
    }

    private static boolean placeQueenHelper(int n, int[][] board, int row) {
        if (row == n) {
            return true;
        }
        for (int col = 0; col < n; col++) {
            if (isValid(board, row, col)) {
                board[row][col] = 1; // 放置皇后
                if (placeQueenHelper(n, board, row + 1)) {
                    return true;
                }
                board[row][col] = 0; // 移除皇后,回溯
            }
        }
        return false;
    }

    private static boolean isValid(int[][] board, int row, int col) {
        for (int i = 0; i < row; i++) {
            if (board[i][col] == 1) return false; // 检查同一列
            if (board[row - col + i][col - i] == 1) return false; // 检查主对角线
            if (board[row - col + i][col + i] == 1) return false; // 检查副对角线
        }
        return true;
    }

    private static void printSolution(int[][] board) {
        for (int[] row : board) {
            for (int val : row) {
                System.out.print(val + " ");
            }
            System.out.println();
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int n = 4; // 棋盘大小
        int[][] board = new int[n][n];
        placeQueen(n, board);
        System.out.println("Total solutions: " + count);
    }
}

题目 2:全排列问题

问题描述:给定一个不含重复数字的序列,返回其所有可能的全排列。

Java 源码

import java.util.ArrayList;
import java.util.List;

public class Permutations {
    public static List<List<Integer>> permute(int[] nums) {
        List<Integer> list = new ArrayList<>();
        for (int num : nums) {
            list.add(num);
        }
        return backtrack(list, new ArrayList<>());
    }

    private static List<List<Integer>> backtrack(List<Integer> list, List<Integer> result) {
        if (list.size() == 0) {
            result.add(new ArrayList<>(list));
            return result;
        }
        for (int i = 0; i < list.size(); i++) {
            List<Integer> newResult = new ArrayList<>(result);
            newResult.add(list.get(i));
            list.remove(i);
            backtrack(list, newResult);
            list.add(i, list.get(i)); // 回溯
        }
        return result;
    }

    public static void main(String[] args) {
        int[] nums = {1, 2, 3};
        List<List<Integer>> result = permute(nums);
        for (List<Integer> perm : result) {
            System.out.println(perm);
        }
    }
}

题目 3:组合总和问题

问题描述:给定一个候选数字的集合(候选数字中的每个数字可以多次选择),保证和的总和不小于目标和,找出所有可能的组合,且每种组合的数字不会重复。
Java 源码

import java.util.ArrayList;
import java.util.List;

public class CombinationSum {
    public static List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> combination = new ArrayList<>();
        backtrack(candidates, target, combination, result, 0);
        return result;
    }

    private static void backtrack(int[] candidates, int target, List<Integer> combination, List<List<Integer>> result, int start) {
        if (target < 0) {
            return;
        }
        if (target == 0) {
            result.add(new ArrayList<>(combination));
            return;
        }
        for (int i = start; i < candidates.length; i++) {
            combination.add(candidates[i]);
            backtrack(candidates, target - candidates[i], combination, result, i); // 允许重复使用同一个数字
            combination.remove(combination.size() - 1); // 回溯
        }
    }

    public static void main(String[] args) {
        int[] candidates = {10, 1, 2, 7, 6, 1, 5};
        int target = 8;
        List<List<Integer>> result = combinationSum(candidates, target);
        for (List<Integer> comb : result) {
            System.out.println(comb);
        }
    }
}

以上题目和代码示例都是经典的回溯算法问题,它们可以帮助你在面试中展示你的算法能力和编程技巧。在实际面试中,除了正确解决问题,清晰地解释你的思路和代码也非常重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/499243.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

是谁?阻止CXL在AI场景大展身手~

CXL虽然被视为业内新宠&#xff0c;但好像在AI场景的应用反而没有得到广泛的响应。 AI场景对内存带宽、容量以及数据一致性有着极高需求&#xff0c;特别是在深度学习训练和推理过程中&#xff0c;大量数据需要在CPU、GPU、加速器以及内存之间快速、高效地流动。CXL作为一种新…

Java基础入门day24

day24 abstract 抽象&#xff1a;似是而非&#xff0c;像又不是&#xff0c;具备某种对象的特征&#xff0c;但不完整 生活中的抽象&#xff1a;动物&#xff0c;并不真实存在的事物 程序中的抽象&#xff1a;不应该被创建的对象&#xff0c;动物近视一种会吃会睡的对象&#…

Netty核心原理剖析与RPC实践16-20

Netty核心原理剖析与RPC实践16-20 16 IO 加速&#xff1a;与众不同的 Netty 零拷贝技术 今天的课程我们继续讨论 Netty 实现高性能的另一个高阶特性——零拷贝。零拷贝是一个耳熟能详的词语&#xff0c;在 Linux、Kafka、RocketMQ 等知名的产品中都有使用&#xff0c;通常用于…

【单调栈】力扣84.柱状图中最大的矩形

上篇文章我们介绍了使用 无重复值 单调栈代码解决 含有重复值 的问题&#xff0c;在文章的最后&#xff0c;留下了一道考察相同思想的题目&#xff0c;今天我们来看看如何套路解决该题。 &#xff08;还没看过前几篇介绍的小伙伴赶快关注&#xff0c;在 「单调栈」 集合里查看…

通过node 后端实现颜色窃贼 (取出某个图片的主体rgb颜色 )

1.需求 我前端轮播图的背景色 想通过每一张轮播图片的颜色作为背景色 这样的话 需要通过一张图片 取出图片的颜色 这个工作通过前端去处理 也可以通过后端去处理 前端我试了试 color-thief 的插件 但是 这个插件是基于canvas 的模式来的 我需要在小程序中使用这个插件 而且是…

HarmonyOS-如何使用ArkTS声明式语法和基础组件,实现待办列表。

介绍 本篇Codelab将介绍如何使用ArkTS声明式语法和基础组件&#xff0c;实现简易待办列表。效果为点击某一事项&#xff0c;替换标签图片、虚化文字。效果如图所示&#xff1a; 相关概念 ArkTS语法&#xff1a;ArkTS是HarmonyOS的主要应用开发语言。ArkTS基于TypeScript&…

2024/3/29(MybatisPlus插件代码生成,静态工具,逻辑删除,枚举处理器.JSON处理器,分页插件,通用分页实体)

jdbc:mysql://localhost:3306/mp?useUnicodetrue&characterEncodingutf8&serverTimezoneUTC 需要这样 日志查看级别

【C++杂货铺】内管管理

目录 &#x1f308;前言&#x1f308; &#x1f4c1; C/C中内存分布 &#x1f4c1; new 和 delete的使用 &#x1f4c1; new 和 delete的优点 &#x1f4c1; new 和 delete的原理 &#x1f4c2; operator new 和 operator delete函数 &#x1f4c2; 内置类型 &#x1f4c2…

代码随想录-DAY4|leetcode-24,19,142,面试题 02.07

文章目录 22. 两两交换链表中的节点19. 删除链表的倒数第N个节点size-n方式删除双指针方式&#xff08;推荐&#xff09; 面试题 02.07. 链表相交142. 环形链表II暴力解法快慢指针&#xff08;推荐&#xff09; 22. 两两交换链表中的节点 leetcode链接&#xff1a;两两交换链表…

怎样一次性给多篇word文档标注拼音?一键批量注音

随着办公自动化的普及&#xff0c;我们经常会遇到需要处理大量Word文档的情况。在这些文档中&#xff0c;有时需要将文字标注上拼音&#xff0c;特别是在处理一些包含生僻字或需要拼音辅助阅读的文档时。然而&#xff0c;手动一篇篇地给Word文档标注拼音不仅效率低下&#xff0…

Docker搭建LNMP环境实战(08):安装php-fpm

1、编写php测试文件 在文件夹&#xff1a;/mnt/hgfs/dockers/test_site/www目录下创建文件&#xff1a;test.php&#xff0c;内容为&#xff1a; <?phpecho "hello world!!!!!! From test.php"; ?>2、编写php-fpm部署配置文件 在文件夹&#xff1a;/mnt/h…

mars3d兼容老版本Chrome 浏览器的附件参考记录

问题 源代码里面是es5的写法&#xff0c;怎么在浏览器上就转换了。 mars3d会将es5转es6吗&#xff1f; 看加载的Cesium.js源代码没有问题&#xff0c;但是模块里面的源代码已经转换了&#xff0c;再低版本浏览器上面会无法运行“Uncaught SyntaxError: Unexpected token ?”…

JVM(一)——内存结构

一. 前言 1、什么是 JVM? 1&#xff09;定义&#xff1a; Java Virtual Machine - java 程序的运行环境&#xff08;java 二进制字节码的运行环境&#xff09; 2&#xff09;好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收功能数组下标越…

测试员再也不怕漏测!花2年总结的这个测试模板太全了!

作为一个测试&#xff0c;最尴尬的莫过于分给你的task&#xff0c;别人做交叉兼容测试的时候&#xff0c;在你负责的内容里找出了很多你没有测试出来的bug。 我也曾因为测试不全被组长在工作群里艾特。说实话&#xff0c;真的恨不得找个地方躲起来。 为了避免自己再次出现类似…

用友BI告诉你,分析指标计算也可以很简单

分析数据&#xff0c;特别是分析财务数据&#xff0c;要计算得分析指标都非常多&#xff0c;涉及的数据来源也是各有不同&#xff0c;一旦哪个环节出了错就一切都得重来。难道分析指标的计算就没有更快更简单的办法了&#xff1f;奥威-用友BI告诉你&#xff0c;分析指标计算有别…

【JDBC编程】基于MySql的Java应用程序中访问数据库与交互数据的技术

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

新家装修选中央空调如何选?认准约克VRF中央空调

在现代家居生活中,追求舒适和健康生活环境的家庭越来越倾向于选择中央空调系统。面对市场上琳琅满目的中央空调品牌,如何挑选一款合适的家用中央空调成为许多消费者的一大难题。今天,我们以约克VRF中央空调为例,深入探讨其特点和优势,为广大家庭提供一个舒适的选择答案。 首先…

IP可以申请SSL证书吗?

目录 背景&#xff1a; 申请IP证书的基本条件&#xff1a; 支持IP地址的证书类型&#xff1a; 为什么要申请IP地址证书&#xff1f; 如何申请IP地址证书 背景&#xff1a; IP地址是可以实现https加密需求的&#xff0c;且IP SSL证书可以完美的解决企业对于IP地址实现http…

标准库不带操作系统移植FreeModbus到STM32

添加FreeModbus代码 首先准备一个空白的标准库项目。 下载FreeModbus源码。 将源码中的modbus文件夹复制到项目路径下&#xff0c;并把demo->BARE->port文件夹的内容也添加进来。 新建一个文件port.c备用。然后打开项目&#xff0c;将上述文件添加至项目&#xff0c;…

Sectigo多域名ssl证书1200元

多域名SSL证书是可以同时保护多个域名的域名型数字证书之一&#xff0c;为个人和企事业单位提供了多样化的数字证书方案。各个正规的CA认证机构所颁发的多域名费SSL证书产品中&#xff0c;Sectigo旗下的多域名SSL证书是使用范围比较广的一款。今天就随SSL盾小编了解Sectigo旗下…
最新文章