力扣 797. 所有可能的路径 解析JS、Java、python、Go、c++

news2025/3/20 5:51:07

深度优先搜索解所有可能的路径问题

题目描述

力扣链接
给你一个有 n 个节点的 有向无环图(DAG),请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特定顺序)

graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j]存在一条有向边)。

示例 1:

输入:graph = [[1,2],[3],[3],[]]
输出:[[0,1,3],[0,2,3]]
解释:有两条路径 0 -> 1 -> 3 和 0 -> 2 -> 3
示例 2:

输入:graph = [[4,3,1],[3,2,4],[3],[4],[]]
输出:[[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]

提示:

n == graph.length
2 <= n <= 15
0 <= graph[i][j] < n
graph[i][j] != i(即不存在自环)
graph[i] 中的所有元素 互不相同
保证输入为 有向无环图(DAG)

解题思路

由于是有向无环图,可以使用深度优先搜索(DFS)遍历所有可能路径。通过回溯法维护当前路径,在到达终点时保存路径到结果集[[2]][[5]]。

关键实现步骤

  1. 维护两个数据结构:
    • ans:存储所有合法路径
    • path:记录当前遍历路径(栈结构)
  2. 从节点0开始DFS
  3. 遍历当前节点的所有邻居:
    • 将邻居节点加入路径
    • 递归处理邻居节点
    • 回溯时弹出最后加入的节点
  4. 当到达终点n-1时,将当前路径加入结果集

代码实现

Java版本

class Solution {
    //最终返回结果
    List<List<Integer>> ans = new ArrayList();
    //保存其中的一条结果
    Deque<Integer> stack = new ArrayDeque();

    public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
        //graph[i] 是一个从节点 i 可以访问的所有节点的列表
        //因为从节点0开始
        stack.offerLast(0);
        //调用
        dfs(graph,0,graph.length-1);
        return ans;
    }


    public void dfs(int[][] graph,int x,int n){
        //x表示当前遍历的节点 n表示要到达的节点
        if(x == n){
            //如果x == n 说明遍历到了最后节点 将stack作为一个结果存入
            ans.add(new ArrayList<Integer>(stack));
            return;
        }
        //graph[x] 表示当前节点x的所有邻居节点
        for(int y:graph[x]){
            //遍历节点x的每个邻居节点
            //1、将y存入
            stack.offerLast(y);
            //递归
            dfs(graph,y,n);
            //回溯
            stack.pollLast();
        }
    }
}

JavaScript版本

var allPathsSourceTarget = function(graph) {
    const ans = [];
    const dfs = (curr, path) => {
        if (curr === graph.length - 1) {
            ans.push([...path]);
            return;
        }
        for (const neighbor of graph[curr]) {
            path.push(neighbor);
            dfs(neighbor, path);
            path.pop();
        }
    };
    dfs(0, [0]);
    return ans;
};

C++版本

class Solution {
public:
    vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
        vector<vector<int>> ans;
        vector<int> path = {0};
        dfs(graph, 0, graph.size()-1, path, ans);
        return ans;
    }
    
private:
    void dfs(vector<vector<int>>& graph, int curr, int target, 
             vector<int>& path, vector<vector<int>>& ans) {
        if (curr == target) {
            ans.push_back(path);
            return;
        }
        for (int neighbor : graph[curr]) {
            path.push_back(neighbor);
            dfs(graph, neighbor, target, path, ans);
            path.pop_back();
        }
    }
};

Go版本

func allPathsSourceTarget(graph [][]int) [][]int {
    var ans [][]int
    var path = []int{0}
    var dfs func(int)
    dfs = func(curr int) {
        if curr == len(graph)-1 {
            ans = append(ans, append([]int{}, path...))
            return
        }
        for _, neighbor := range graph[curr] {
            path = append(path, neighbor)
            dfs(neighbor)
            path = path[:len(path)-1]
        }
    }
    dfs(0)
    return ans
}

Python版本

class Solution:
    def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
        ans = []
        path = [0]
        n = len(graph)
        
        def dfs(curr):
            if curr == n - 1:
                ans.append(list(path))
                return
            for neighbor in graph[curr]:
                path.append(neighbor)
                dfs(neighbor)
                path.pop()
        
        dfs(0)
        return ans

复杂度分析

  • 时间复杂度:O(2^N * N),每个节点最多有2种选择(选或不选),路径最长为N
  • 空间复杂度:O(N),递归栈深度和路径存储空间[[6]][[8]]

总结

该问题展示了DFS在图遍历中的典型应用。通过维护路径栈实现回溯,可以高效地遍历所有可能路径。不同语言实现时需要注意:

  1. Go/Python需要显式复制路径切片
  2. JavaScript通过闭包简化参数传递
  3. C++使用vector引用传递提升效率[[4]][[9]]

参考:[[1]][[2]][[5]][[7]]

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

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

相关文章

蓝桥与力扣刷题(蓝桥 组队)

题目&#xff1a;作为篮球队教练&#xff0c;你需要从以下名单中选出 1 号位至 5 号位各一名球员&#xff0c;组成球队的首发阵容。 每位球员担任 1号位至 5号位时的评分如下表所示。请你计算首发阵容 1 号位至 5 号位的评分之和最大可能是多少&#xff1f; 本题为填空题&…

AI Agent系列(六) -基于ReAct架构搭建LLM Agent(Deepseek)

AI Agent系列【六】 一、 ReAct1.1 ReAct 的处理过程&#xff1a;1.1 代码结构 二、 Python代码实现2.1 通过Zero-shot 实现python代码实例Python代码示例1&#xff1a;python代码实现示例2 一、 ReAct ReAct 是 Reseaning 和 Action 两个词的前缀合成&#xff0c;代表着先推…

AnyTouch:跨多个视觉触觉传感器学习统一的静态动态表征

25年3月来自人大、武汉科技大学和北邮的论文“AnyTouch: Learning Unified Static-dynamic Representation Across Multiple Visuo-tactile Sensors”。 视觉触觉传感器旨在模拟人类的触觉感知&#xff0c;使机器人能够精确地理解和操纵物体。随着时间的推移&#xff0c;许多精…

YOLOv11 目标检测

本文章不再赘述anaconda的下载以及虚拟环境的配置&#xff0c;博主使用的python版本为3.8 1.获取YOLOv11的源工程文件 链接&#xff1a;GitHub - ultralytics/ultralytics: Ultralytics YOLO11 &#x1f680; 直接下载解压 2.需要自己准备的文件 文件结构如下&#xff1a;红…

VSCode C/C++ 环境搭建指南

一、前言 Visual Studio Code&#xff08;简称 VSCode&#xff09;是一款轻量级且功能强大的跨平台代码编辑器&#xff0c;凭借丰富的插件生态和高度的可定制性&#xff0c;深受开发者喜爱。对于 C/C 开发者而言&#xff0c;在 VSCode 中搭建开发环境&#xff0c;能够获得灵活…

Python 中下划线 “_” 的多面性:从变量到约定

# Python中下划线“_”的多面性&#xff1a;从变量到约定 在Python的语法体系里&#xff0c;下划线“_”看似毫不起眼&#xff0c;实则扮演着极为重要且多样化的角色。它不仅能作为普通变量参与编程&#xff0c;更在多个特殊场景下有着独特的用途与约定。深入理解下划线的各种…

Vue3项目开发:状态管理实践指南

# Vue3项目开发&#xff1a;状态管理实践指南 一、引言 背景介绍 在Vue项目中&#xff0c;状态管理是一个非常重要的话题。合理的状态管理能够帮助我们更好地组织和管理数据&#xff0c;提升项目的可维护性和可扩展性。本文将深入探讨Vue3项目中状态管理的最佳实践&#xff0c;…

数据结构-------栈

顺序栈&#xff1a; 一、数据结构定义 数据元素 DATATYPE typedef struct person {char name[32];char sex;int age;int score; } DATATYPE;顺序栈结构 SeqStack typedef struct list {DATATYPE *head; // 栈空间首地址int tlen; // 栈总容量&#xff08;total leng…

机器学习概要

文章目录 一、什么是机器学习 二、机器学习的种类 1. 有监督学习 2. 无监督学习 3.强化学习 三、机器学习的应用 四、机器学习的步骤 1. 数据的重要性 2. 数据和学习的种类 3. 可视化 一、什么是机器学习 机器学习指的是计算机根据给定的问题、课题或环境进行学习&a…

【LangChain入门 2 Model组件】开始!LLM Models简单对话

文章目录 一、使用langchain_ollama二、采用DeepSeek的API三、Model 介绍3.1 OllamaLLM 预训练模型3.2 ChatOllama 聊天预训练模型3.3 OllamaEmbeddings 实现一个helloworld&#xff0c;跑通一个简单的对话。 后面章节会正式介绍LangChain的各个功能。 后台llm的端口可以任意选…

C++20 中线程管理与取消机制的深度剖析

文章目录 std::jthread&#xff1a;更智能的线程管理背景与优势构造函数与 std::stop_token 的集成 std::stop_token、std::stop_source 和 std::stop_callback&#xff1a;灵活的取消机制std::stop_token&#xff1a;取消请求的指示器std::stop_source&#xff1a;取消请求的发…

Vue3 核心特性解析:Suspense 与 Teleport 原理深度剖析

Vue3 核心特性解析&#xff1a;Suspense 与 Teleport 原理深度剖析 一、Teleport&#xff1a;突破组件层级的时空传送 1.1 实现原理图解 #mermaid-svg-75dTmiektg1XNS13 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-s…

FPGA——实现LED流水灯

文章目录 一、Quartusll_18.1和VS Code软件的关联二、DE2-115的时钟电路三、流水灯的分层次设计四、总结 一、Quartusll_18.1和VS Code软件的关联 1.先打开Quartus II 软件&#xff0c;然后选择菜单栏“Tools”下的“Options…”。 2.点击“Options…”&#xff0c;在弹出的对…

Excel 小黑第12套

对应大猫13 涉及金额修改 -数字组 -修改会计专用 VLOOKUP函数使用&#xff08;查找目标&#xff0c;查找范围&#xff08;F4 绝对引用&#xff09;&#xff0c;返回值的所在列数&#xff0c;精确查找或模糊查找&#xff09;双击填充柄就会显示所有值 这个逗号要中文的不能英…

滚动元素的新api

点击的时候需要双重视图滚动 itemClick(id) {// 滚动到对应位置this.$nextTick(() > {// 找到对应 id 在 initList2 中的索引const index this.initList2.findIndex((item) > item.id Number(id));if (index ! -1) {// 获取所有菜单项const menuItems document.queryS…

多机调度问题(C语言)

代码如下&#xff1a; #include<stdio.h> #include<stdlib.h>int compare(void* a, void* b)//比较函数&#xff0c;用于qsort按处理时间从大到小排序 {return *(int*)a - *(int*)b; }int LPT(int jobs[], int n, int m)//多机调度问题的LPT算法 {qsort(jobs, n, …

烽火HG680-KB_海思HI3798MV310_安卓9.0_U盘强刷固件包及注意点说明

之前发布过这个固件包&#xff0c;关于烽火HG680-KA&#xff0f;HG680-KB_海思HI3798MV310_安卓9.0_U盘强刷固件包详细说明一下&#xff0c;汇总总结一些常遇到的情况&#xff0c;这次固件会分开发布&#xff0c;以免混淆。 上一个帖子地址&#xff1a;烽火HG680-KA&#xff0…

996引擎 - 红点系统

996引擎 - 红点系统 总结NPC 红点(TXT红点)Lua 红点1. Red_Point.lua2. UI_Ex.lua参考资料以下内容是在三端 lua 环境下测试的 总结 红点系统分几个部分组成。 M2中设置变量推送。 配置红点表。 Envir\Data\cfg_redpoint.xls 2.1. UI元素中找到ID填写 ids 列。 主界面挂载…

3.17BUUCTF练习day1

BUUCTF练习day1 [极客大挑战 2019]EasySQL1&#xff08;字符型&#xff0c;账号密码型&#xff0c;get型&#xff09; 判断闭合方式 在用户名输入1‘&#xff0c;此时密码先输入任何数字时&#xff0c;出现语法错误 说明闭合方式为单引号闭合&#xff0c;在判断完闭合方式后…

【贪心算法】柠檬水找零

1.题目解析 860. 柠檬水找零 - 力扣&#xff08;LeetCode&#xff09; 2.讲解算法原理 分情况讨论 5---》直接收下 10---》找五元&#xff0c;收下 20----》105△ ----》555 由于5元更有用&#xff0c;则尽可能保留5元 3.代码 class Solution {public boolean lemonadeCh…