LeetCode_BinaryTree_1129. Shortest Path with Alternating Colors 颜色交替的最短路径【BFS求最短路径】【java】【中等】

2023-11-12

一,题目描述

英文描述

You are given an integer n, the number of nodes in a directed graph where the nodes are labeled from 0 to n - 1. Each edge is red or blue in this graph, and there could be self-edges and parallel edges.

You are given two arrays redEdges and blueEdges where:

redEdges[i] = [ai, bi] indicates that there is a directed red edge from node ai to node bi in the graph, and
blueEdges[j] = [uj, vj] indicates that there is a directed blue edge from node uj to node vj in the graph.
Return an array answer of length n, where each answer[x] is the length of the shortest path from node 0 to node x such that the edge colors alternate along the path, or -1 if such a path does not exist.

中文描述

在一个有向图中,节点分别标记为 0, 1, ..., n-1。图中每条边为红色或者蓝色,且存在自环或平行边。

red_edges 中的每一个 [i, j] 对表示从节点 i 到节点 j 的红色有向边。类似地,blue_edges 中的每一个 [i, j] 对表示从节点 i 到节点 j 的蓝色有向边。

返回长度为 n 的数组 answer,其中 answer[X] 是从节点 0 到节点 X 的红色边和蓝色边交替出现的最短路径的长度。如果不存在这样的路径,那么 answer[x] = -1。

示例与说明

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shortest-path-with-alternating-colors
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二,解题思路

由于是红蓝交替、蓝红交替都可以,所以可以想象有一个虚拟的节点-1指向0:

如果-1=》0为红色路径,那么0=》下一个节点就要选择蓝色路径

否则正好相反。

由于是求从0开始的最短路径,所以BFS最合适不过了,每次可以得到一层的结果,需要注意两点:

  • 对遍历过的节点,要添加对应的标记,如lastColor为red,需要标记red路径已经使用过,再次遍历到该节点时,需要跳过;
  • 每遍历完一层,需要变换颜色(BFS层次遍历,需要记录当前队列元素数目,这样就可以每次遍历一层的节点);

三,AC代码

Java

import java.util.*;
class Solution {
    public int[] shortestAlternatingPaths(int n, int[][] redEdges, int[][] blueEdges) {
        int[] ans = new int[n];
        for (int i = 0; i < n; i++) ans[i] = Integer.MAX_VALUE;;

        Map<Integer, List<Integer>> redNext = new HashMap<>();
        Map<Integer, List<Integer>> blueNext = new HashMap<>();
        for (int i = 0; i < redEdges.length; i++) {
            if (!redNext.containsKey(redEdges[i][0])) {
                redNext.put(redEdges[i][0], new ArrayList<>());
            }
            List<Integer> list = redNext.get(redEdges[i][0]);
            list.add(redEdges[i][1]);
        }

        for (int i = 0; i < blueEdges.length; i++) {
            if (!blueNext.containsKey(blueEdges[i][0])) {
                blueNext.put(blueEdges[i][0], new ArrayList<>());
            }
            List<Integer> list = blueNext.get(blueEdges[i][0]);
            list.add(blueEdges[i][1]);
        }

        // false: blue指向当前节点, true: red指向当前节点
        bfs(redNext, blueNext, true, ans);
        bfs(redNext, blueNext, false, ans);

        for (int i = 0; i < n; i++) {
            if (ans[i] == Integer.MAX_VALUE) {
                ans[i] = -1;
            }
        }

        return ans;
    }
    // false: blue指向当前节点, true: red指向当前节点
    public void bfs (Map<Integer, List<Integer>> redNext, Map<Integer, List<Integer>> blueNext, boolean lastColor, int[] ans) {
        int n = ans.length;
        boolean[] redVisited = new boolean[n];
        boolean[] blueVisited = new boolean[n];
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(0);
        int step = 0;
        if (lastColor) redVisited[0] = true;
        else blueVisited[0] = true;
        while (!queue.isEmpty()) {
            int size = queue.size();
            while (size-- != 0) {
                int node = queue.peek();
                ans[node] = Math.min(ans[node], step);
                queue.poll();
                // 红色指向当前节点
                if (lastColor && blueNext.containsKey(node)) {
                    for (int num : blueNext.get(node)) {
                        if (!blueVisited[num]) {
                            queue.add(num);
                            blueVisited[num] = true;

                        }
                    }
                }
                // 蓝色指向当前节点
                else if (!lastColor && redNext.containsKey(node)) {
                    for (int num : redNext.get(node)) {
                        if (!redVisited[num]) {
                            queue.add(num);
                            redVisited[num] = true;

                        }
                    }
                }
            }
            lastColor = !lastColor;//  !!!
            step++;
        }
    }
}

四,解题过程

第一搏

这是一次面试的时候遇到的题目,当时没想到用BFS如何处理,一直陷入在DFS如何解决重复遍历同一节点的问题,虽然面试官提示用BFS,但是仍没有领悟到关键o( ̄┰ ̄*)ゞ

第二搏

红蓝交替、蓝红交替都算数,所以要走两遍BFS。。。于是将其抽离为一个单独的方法,注意颜色的切换

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeetCode_BinaryTree_1129. Shortest Path with Alternating Colors 颜色交替的最短路径【BFS求最短路径】【java】【中等】 的相关文章

随机推荐

  • pytorch——torch.squeeze() 和torch.unsqueeze()的用法

    torch squeeze torch squeeze 这个函数主要对数据的维度进行压缩 去掉维数为1的的维度 比如是一行或者一列这种 一个一行三列 1 3 的数去掉第一个维数为一的维度之后就变成 3 行 torch squeeze a 就
  • 项目答辩PPT(一)

    以 运动APP 为例展开 1 项目整体介绍 定位和需求 在银行工作的王小姐是个健身爱好者 从制订健身计划 到约人一起跑步 再到周末预订场地和家人打一场羽毛球赛 她用一部手机轻松搞定 现在有了手机APP 运动方便多了 王小姐的运动方式是如今都
  • QT创建右键快捷菜单

    0 目标 在Qcommbobox右键出来菜单 点击BCC校验 自动算出校验值填入编辑框 1 UI界面选择Action editor 新建action 记住对象名 actionBCC 右键action 点击转到槽 选择triggered 点击
  • 指针(一)——指针与二级指针

    一 指针理解 指针是一个变量 用来存放地址的变量 指针变量 是一个变量 是指有一个存储空间 里面放的是指针 变量指针 变量的地址 指针的存在是为了方便计算机的内存管理 经过计算和权衡 我们发现 一个字节给一个地址是比较合适的 在32位的机器
  • 给wangeditor添加上标、下标功能

    我使用的wangeditor没有上标和下标功能 以下是自己添加功能的方法 1 设计功能的函数和原型 Sup menu 构造函数 function Sup editor this editor editor this elem div cla
  • 高性能MySQL实战(一):表结构

    最近因需求改动新增了一些数据库表 但是在定义表结构时 具体列属性的选择有些不知其所以然 索引的添加也有遗漏和不规范的地方 所以我打算为创建一个高性能表的过程以实战的形式写一个专题 以此来学习和巩固这些知识 1 实战 我使用的 MySQL 版
  • 【深度学习】 Python 和 NumPy 系列教程(七):Python函数

    目录 一 前言 二 实验环境 三 Python函数基础 1 定义函数 2 参数传递 3 函数调用 4 返回值 5 函数文档字符串 四 将函数存储在模块中 1 创建模块 2 导入模块 a import 模块名 b from 模块名 impor
  • github.io出现的问题及解决方案

    github io出现的问题及解决方案 个人博客 github io出现的问题及解决方案 1 你的连接不是专用连接 放假回家后打开自己的博客 发现无法打开博客 一开始以为是调样式时不小心搞坏了 打开别人的githunb io博客发现都会出问
  • Python删除字符串中连续重复字符,保留所有去重后字符

    看了很多攻略 但都是全部去除字符串中所有的重复字符或者全部去除字符串所有相邻的重复字符 如果希望得到字符串中相邻字符去重后的全部字符 比如字符串a abbcccd222aaabbbddfff6e 去重后能得到 abcd2abdf6e 那可以
  • CMake中if的使用

    CMake中的if命令用于有条件地执行一组命令 其格式如下 if
  • 判断字符串是否为回文串的Java实现方法(收藏自力扣)

    先把字符串转成字符数组 可以调用toCharArray 方法 public char toCharArray 将此字符串转换为一个新的字符数组 Returns 一种新分配的字符数组 其长度是该字符串的长度 其内容被初始化为包含由该字符串表示
  • 时间序列模型Prophet使用详细讲解

    之前我们已经讲过了如何在Windows系统下安装Python版本的Prophet 详细见这里 接下来的几个部分 我们说下如何使用Prophet 以此来体验下Prophet的丰富内容 内容会比较多 主要翻译自官方文档 教程中使用的数据集可在
  • DAP数据分析平台权限体系说明

    数据对于企业来说是非常重要的 所以产品的安全性需要有所保证 而权限分配就是一种保障方式 通过不同权限查看到不同的数据进行数据隔离 保障数据的安全性 DAP数据分析平台通过授权管理进行角色授权 配置授权 业务授权实现三权分立 不同的用户能看到
  • 后端解决跨域

    对于跨域 相信同学们都有所了解 前端的跨域的若干种方式 大家也都知道 什么 JSONP iframe domain 等等 但是我们今天的主题 不是前端跨域 而是后端跨域 一旦提及到跨域 就会想到同源策略 那我们就先来回顾跨域和同源策略 什么
  • upload-labs第五关 pass-05 大小写绕过

    六 pass 05 大小写绕过 源码 is upload false msg null if isset POST submit if file exists UPLOAD ADDR deny ext array php php5 php4
  • 封装浏览器外壳

    Net本身包含WebBrower控件 可惜内核是IE http www cnblogs com M Silencer p 5846494 html 参考以上文章 通过一些控件可以再窗体中嵌入webkit内核的浏览器 目前在尝试CefShar
  • 快手广告推广效果由哪些因素决定?快手广告能满足哪些推广目标?

    快手广告用户与你的行业用户一致快手用户为三线城市 95后年轻用户为主 同时其用户人群也在大城市进行渗透 那么快手广告推广效果由哪些因素决定 快手广告能满足哪些推广目标 一 快手广告推广效果由哪些因素决定 1 广告的推广效果可以分为曝光效果
  • 大数据代表技术:Hadoop、Spark、Flink、Beam

    大数据代表技术 Hadoop Spark Flink Beam Hadoop 从2005年到2015年 说到大数据都是讲hadoop Hadoop是一整套的技术框架 不是一个单一软件 它是一个生态系统 Hadoop有两大核心 第一个是它解决
  • ubuntu系统安装pangolin

    ubuntu 安装 pangolin 1 安装pangolin依赖项以及安装过程中用到的工具 2 创建安装目录 3 下载pangolin源文件 4 安装pangolin 1 安装pangolin依赖项以及安装过程中用到的工具 ctrl al
  • LeetCode_BinaryTree_1129. Shortest Path with Alternating Colors 颜色交替的最短路径【BFS求最短路径】【java】【中等】

    一 题目描述 英文描述 You are given an integer n the number of nodes in a directed graph where the nodes are labeled from 0 to n 1