多路递归的一些算法题

news2025/1/16 19:50:46

前言

首先我想讲一下,我对多路递归的理解吧,我认为多路递归就是循环中套回调,对于循环有几次就是几叉树,就好比我们常用的二叉树的dfs(node.left) 和 dfs(node.right)等前中后序遍历,也就是for (int i = 0; i < 2; i++) { TreeSet node = i == 0 ? node.left : node.right; dfs(node); }就是一个循环两次的for循环。实在无法理解就画图,好比二叉树画四个方格,1为递归出口,2为左指针,3为右指针,4回溯返回的结果

全排列

这一题也就是高中的排列组合,填空问题,n!。第一个空从n个数选一个,第二个空选除第一个空以外的数 n - 1 依次类推

全排列的链接

https://leetcode.cn/problems/VvJkup/icon-default.png?t=N7T8https://leetcode.cn/problems/VvJkup/

思路分析: 多路递归 + 回溯 + 剪枝 + 引入三个全局变量

多路递归:有几个数树分几个叉

回溯: 归的时候,返回我们修改前的状态

剪枝: 剪掉不需要的,比如遍历了A了下次就不要处理A了 

全局变量 result: 返回最终的结果

                temp:存放到叶子结点的值

                cheak:判断该元素是否枚举过了(剪枝)

这些说明代码注释里面都介绍了!

关于123的全排列的决策树 

public class MyTest1 {
    private List<List<Integer>> result;
    private List<Integer> temp;//存放枚举的结果
    private boolean[] cheak;//判断是否已经枚举过了

    public List<List<Integer>> permute(int[] nums) {
        result = new ArrayList<>();
        temp = new ArrayList<>();
        cheak = new boolean[nums.length];
        dfs(nums);
        return result;
    }
    //深搜(枚举) + 回溯(恢复现场) + 剪枝(cheak变量标记是否不需要遍历)
    private void dfs(int[] nums) {
        //递归出口
        if (temp.size() == nums.length){
            result.add(new ArrayList<>(temp));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (!cheak[i]) {
                temp.add(nums[i]);
                cheak[i] = true;
                dfs(nums);
                //递归完毕,进行回溯的时候说明已经是搞完了再往上返回
                //恢复现场
                cheak[i] = false;
                temp.remove(temp.size() - 1);
            }
        }
    }
}

子集

子集就是也是高中数学的基础知识,比如 1 2 的子集是{空集},{1},{2},{1,2},其实就是子序列也就是不去重的子集。

. - 力扣(LeetCode)

 思路分析:  这一题主要有两种解法,但是本博客就介绍一种

             解法一:双路递归的二叉分为选和不选

全局变量 + 多路递归 + 回溯  没有剪枝(因为只有选不选,不会出现枚举重复元素)

全局变量path: 递了总集的元素次结束,存放

二路递归:选或者不选,来分为二叉树

回溯:选的时候,往上归的时候要恢复现场

注释我都详解了。

             解法二:按照子集个数分,比如空集是个数为0

解法一的决策树

 解法二的决策树

注意这是解法一的代码,我并没有写解法二的代码 

package study2.day10;

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

//子集
public class MyTest5 {
    private List<Integer> path;//定义叶子结点存的内容
    private List<List<Integer>> result;//返回值

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

    private void dfs(int[] nums, int index) {
        if (index == nums.length) {
            result.add(new ArrayList<>(path));
            return;
        }

        // 不选择当前元素
        dfs(nums, index + 1);

        // 选择当前元素
        path.add(nums[index]);
        dfs(nums, index + 1);
        path.remove(path.size() - 1);//回溯(恢复状态)
    }

    public static void main(String[] args) {
        new MyTest5().subsets(new int[]{1,2,3});
    }
}

 岛屿数量

岛屿数量也就是抱团1的数量,其中1表示地面,0表示海洋,这个是不是很像围棋,1没有气了就是一个岛了。这个题,其实和我写的博客(腐烂的苹果题目一样)但是我还是写错了,这个和那个唯一的区别,就是那个是同时扩散的bfs,这个是单个遍历的dfs

 http://t.csdnimg.cn/q9PFM  这是腐烂苹果博客的链接

 思路分析: 

                解法一:bfs

                解法二:dfs

解法一: bfs也就是借助了队列这个数据结构来保证回调的顺序

        1.创建一个队列(queue)用来保存回调的顺序

        2.遇到 1 入队列,并且标记这个元素已经被扫描过了 vis[i][j] = true

        3.队列不为空表示四周有陆地,继续将陆地并且没有被扫描过添加入队列继续遍历

解法二:dfs就是使用让计算机中的栈内存来当一个栈的数据结构供你使用

        1.遇到1,进入递归的dfs并且标记为被扫描

        2.和上述3一样就不一一介绍了

公共代码都一样只不过是调用的函数不一样: 

公共代码

 int[] dx = {0, 0, -1, 1};
    int[] dy = {1, -1, 0, 0};
    boolean[][] vis = null;//判断是否判断过
    int m = 0;
    char[][] grid = null;
    int n = 0;
    public int solve (char[][] grid) {
        this.grid = grid;
        m = grid.length;
        n = grid[0].length;
        int count = 0;
        vis = new boolean[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (!vis[i][j] && grid[i][j] == '1'){
                    bfs(vis, i, j);//逐个遍历
                    count++;
                }
            }
        }
        return count;
    }

解法一代码:

//解法一的bfs代码
    private void bfs(boolean[][] vis, int i, int j) {
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{i,j});
        vis[i][j] = true;
        while(!queue.isEmpty()){
            int[] arr = queue.poll();
            int a = arr[0], b = arr[1];
            for (int k = 0; k < 4; k++) {
                int x = a + dx[k], y = b + dy[k];
                if (x >= 0 && y >= 0 && x < m && y < n && !vis[x][y] &&  grid[x][y] == '1'){
                    queue.offer(new int[]{x, y});
                    vis[x][y] = true;
                }
            }
        }
    }

解法二代码:

 //深搜,全部的1都搜索
    private void dfs(boolean[][] vis, int i, int j) {
        vis[i][j] = true;
        for (int k = 0; k < 4; k++) {
            int x = i + dx[k], y = j + dy[k];
            if (x >= 0 && y >= 0 && x < m && y < n && !vis[x][y] &&  grid[x][y] == '1'){
                dfs(vis, x, y);
            }
        }
    }

总结

非常感谢您的支持和鼓励!制作博客确实需要付出很多心血,尤其是分享个人经验和解决问题的方法。如果我的回答对您有帮助,我会很高兴为您点个三连。另外,祝您周末愉快,愿您的每一天都充满快乐和成就!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AIGC - SD(中英文本生成图片) + PaddleHub/HuggingFace + stable-diffusion-webui

功能 stable-diffusion(文本生成图片)webui-win搭建&#xff08;开启api界面汉化&#xff09;PaddleHubHuggingFace: SD2&#xff0c;中文-alibaba/EasyNLP stable-diffusion-webui 下载与安装 环境相关下载 python&#xff08;文档推荐&#xff1a;Install Python 3.10.6 …

区块链技术与应用学习笔记(1-4节)——北大肖臻课程

目录 1. 区块链初识(课程简介&#xff09; 被过度炒作&#xff0c;落地应用有限&#xff1f; 下一代的价值互联网&#xff1f;世界上最慢的数据库&#xff1f; 2. BTC-密码学原理&#xff08;比特币&#xff09; 1)哈希 哈希函数特点 个人学习所得 2)签名 个人对于…

U-boot 21.10 启动流程梳理

目录 背景平台启动入口确认启动源码DuoS_SG2000_RISCVLubancat2_RK3568_ARM 初始化流程board_init_fboard_init_r 参考 背景 设备&#xff1a;MilkV Duo S 版本&#xff1a;U-boot 2021.10 编译命令 # Milkv-DuoS SD卡版本&#xff0c;对应[board]与[config]分别为&#xff1…

Leetcode_相交链表

✨✨所属专栏&#xff1a;LeetCode刷题专栏✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 题目&#xff1a; 题解&#xff1a; 看到这个题目首先我们要排除链表逆置的想法&#xff0c;如图、因为c1节点只有一个next指针&#xff0c;逆置后不可能同时指向a2和b3节点。 其次有的的同学…

24深圳杯AC题完整思路+可执行代码+参考论文!!!!

比赛题目的完整版思路可执行代码数据参考论文都会在第一时间更新上传的&#xff0c;大家可以参考我往期的资料&#xff0c;所有的资料数据以及到最后更新的参考论文都是一次付费后续免费的。注意&#xff1a;&#xff08;建议先下单占坑&#xff0c;因为随着后续我们更新资料数…

【AIGC调研系列】大型语言模型如何减少幻觉生成

在解读大型语言模型&#xff08;LLMs&#xff09;中的长格式事实性问题时&#xff0c;我们首先需要认识到这些模型在生成内容时可能会产生与既定事实不一致的情况&#xff0c;这种情况通常被称为“幻觉”[2][3]。这种现象不仅可能导致信息的误传&#xff0c;还可能对社会造成误…

新时代凌迟:考研

我不喜欢上班&#xff0c;但我很欣赏老板的品味&#xff0c;因为咱们公司竟然还在订阅报纸&#xff0c;而且只有一份&#xff0c;《中国青年报》。 这份报纸我最喜欢看的是“冰点周刊”专栏&#xff0c;因为这个栏目能让读者相信&#xff1a;报纸远远可以超越一天的生命。 昨天…

跨境代买淘宝系统,跨境代采系统,淘宝代购系统,淘宝代购集运系统,1688代采系统

淘宝代购系统是一种集成的电商平台服务&#xff0c;主要针对海外用户提供购买中国大陆商品的便利通道。以下是其核心功能与特点&#xff1a; 多语言支持&#xff1a;为了满足全球用户的需求&#xff0c;代购系统提供多语言界面&#xff0c;让不同国家和地区的用户都能方便地浏…

c++初阶——类和对象(下)

大家好&#xff0c;我是小锋&#xff0c;今天我们来学习我们类和对象的最后一个章节&#xff0c;我们本期的内容主要是类和对象的一些细节进行讲解 再谈构造函数 我们在初始化时有两种方式一种是函数体内初始化&#xff0c;一种是初始化列表 我们先来看看日期类的初始化 构造…

Web3技术解析:区块链在去中心化应用中的角色

引言 在过去几年中&#xff0c;Web3技术已经成为了互联网领域的一个热门话题。作为区块链技术的延伸&#xff0c;Web3不仅仅是数字货币的代名词&#xff0c;更是一个能够为各种应用提供去中心化解决方案的强大工具。本文将深入探讨区块链在Web3去中心化应用中的关键角色&#…

【考研数学】武忠祥考研课优缺点大盘点

虽然每年大家推荐的最多的是张宇和汤家凤&#xff0c;但是我强烈推荐武忠祥老师&#xff01; 武忠祥老师真宝藏老师&#xff0c;他讲课不像张宇老师那样段子频出&#xff0c;也不想汤家凤老师那样&#xff0c;武忠祥老师有自己的方法论&#xff0c;真的有点东西&#xff0c;武…

一周学会Django5 Python Web开发-Django5 ORM执行SQL语句

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计49条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

AI工具集:解锁智能新境界,一站式解决你的所有需求!

在这个信息爆炸的时代&#xff0c;我们每天都在与大量的数据和信息打交道。如何高效地处理这些信息&#xff0c;提高工作效率和生活品质&#xff0c;成为了我们亟待解决的问题。而AI工具集(AI-321.com)的出现&#xff0c;无疑为我们提供了一把解锁智能新境界的钥匙。 AI-321 | …

基于streamlit快速部署机器学习项目(Public URL)

基于streamlit的AIGC项目前端展示 1.Streamlit 简介与入门1.1 安装 Streamlit1.2 开发Streamlit应用程序1.3 启动并运行1.3.1 本地运行1.3.2 部署 现在LLM技术发展迅速&#xff0c;很多人在学习的时候&#xff0c;都想展示效果&#xff0c;并且想部署在服务器上&#xff0c;但是…

Zephyr sensor子系统学习

一、背景 2023年7月份nRF Connect SDK 2.4.0最新版本&#xff0c;使用的Zephyr V3.3版本。从Zephyr 3.5版本在子系统中加入了sensing子系统。 现在最新的nRF Connect SDK 2.6.0 release支持v3.5.99-ncs1&#xff0c;已经支持sensing子系统 nRF52840现在官方支持两个传感器de…

Rust中的函数指针

什么是函数指针 通过函数指针允许我们使用函数作为另一个函数的参数。函数的类型是 fn &#xff08;使用小写的 ”f” &#xff09;以免与 Fn 闭包 trait 相混淆。fn 被称为 函数指针&#xff08;function pointer&#xff09;。指定参数为函数指针的语法类似于闭包。 函数指…

阿里前端常考vue面试题汇总_阿里高级vue面试题

改变 ![](https://img-blog.csdnimg.cn/img_convert/b736620bcd29f08f3685022ab5583d8b.webp?x-oss-processimage/format,png)你会发现&#xff0c; **只有改变的栏目才闪烁&#xff0c;也就是进行重绘** &#xff0c;数据没有改变的栏目还是保持原样&#xff0c;这样就大大节…

(3)C程序可执行文件的生成过程

原文链接&#xff1a;https://www.jianshu.com/p/b7e44f749211 一、可执行文件的生成 我们先通过一个简单C程序&#xff0c;回顾一下可执行文件的生成过程。 ​​​​​​​ ​​​​​​​ 可执行文件的生成过程如下图&#xff1a; 如图&#xff0c;可执行文…

Java学习路线及自我规划

荒废了一段时间&#xff0c;这段时间的总结开始了JavaWeb的学习但是困难重重&#xff0c;例如Maven&#xff0c;Vue的路由等&#xff0c;所以我反省了一段时间&#xff0c;因为基础薄弱&#xff0c;加之学习的资源是速成视频&#xff0c;导致大厦将倾的局面&#xff08;也算不上…

为什么如果重写了某个类的equals方法,还必须重写对应的hashcode方法?

为什么如果重写了某个类的equals方法&#xff0c;还必须重写对应的hashcode方法&#xff1f; 答&#xff1a; 保证equals相同的两个对象hashcode必须相同的原则。不重写hashcode方法的的话&#xff0c;若用hashmap/hashset等散列表存储这个类&#xff0c;可能会出现两个相同对…