LC-1377. T 秒后青蛙的位置(DFS、BFS)

news2025/2/24 9:11:13

1377. T 秒后青蛙的位置

难度困难57

给你一棵由 n 个顶点组成的无向树,顶点编号从 1n。青蛙从 顶点 1 开始起跳。规则如下:

  • 在一秒内,青蛙从它所在的当前顶点跳到另一个 未访问 过的顶点(如果它们直接相连)。
  • 青蛙无法跳回已经访问过的顶点。
  • 如果青蛙可以跳到多个不同顶点,那么它跳到其中任意一个顶点上的机率都相同。
  • 如果青蛙不能跳到任何未访问过的顶点上,那么它每次跳跃都会停留在原地。

无向树的边用数组 edges 描述,其中 edges[i] = [ai, bi] 意味着存在一条直接连通 aibi 两个顶点的边。

返回青蛙在 t 秒后位于目标顶点 target 上的概率。与实际答案相差不超过 10-5 的结果将被视为正确答案。

示例 1:

img

输入:n = 7, edges = [[1,2],[1,3],[1,7],[2,4],[2,6],[3,5]], t = 2, target = 4
输出:0.16666666666666666 
解释:上图显示了青蛙的跳跃路径。青蛙从顶点 1 起跳,第 1 秒 有 1/3 的概率跳到顶点 2 ,然后第 2 秒 有 1/2 的概率跳到顶点 4,因此青蛙在 2 秒后位于顶点 4 的概率是 1/3 * 1/2 = 1/6 = 0.16666666666666666 。 

示例 2:

img

输入:n = 7, edges = [[1,2],[1,3],[1,7],[2,4],[2,6],[3,5]], t = 1, target = 7
输出:0.3333333333333333
解释:上图显示了青蛙的跳跃路径。青蛙从顶点 1 起跳,有 1/3 = 0.3333333333333333 的概率能够 1 秒 后跳到顶点 7 。 

提示:

  • 1 <= n <= 100
  • edges.length == n - 1
  • edges[i].length == 2
  • 1 <= ai, bi <= n
  • 1 <= t <= 50
  • 1 <= target <= n

BFS模拟

BFS模拟,在遍历每个节点时,先查看当前节点的邻接节点是不是都访问过了,如果都访问过了,说明走不动了,原地踏步,将该节点加入到队列中,不然就将没访问过的节点加入到队列中。一共循环t次,最后找队列中值 = target的元素

class Solution {
    public double frogPosition(int n, int[][] edges, int t, int target) {
        if(n == 1 && t == target) return 1.0;
        if(n == 1 && t != target) return 0.0;
        List<Integer>[] g = new ArrayList[n];
        Arrays.setAll(g, e -> new ArrayList<>());
        for(int[] e : edges){
            int x = e[0]-1, y = e[1]-1;
            g[x].add(y);
            g[y].add(x);
        }
        target--;
        Deque<Pair<Integer, Double>> dq = new ArrayDeque<>();
        boolean[] vis = new boolean[n];
        dq.addLast(new Pair<>(0, 1.0));
        vis[0] = true;
        int step = 0;
        while(!dq.isEmpty()){
            int size = dq.size();
            while(size-- > 0){
                Pair<Integer, Double> p = dq.pollFirst();
                int s = g[p.getKey()].size();
                for(int y : g[p.getKey()]){
                    if(vis[y])
                        s -= 1;
                }
                if(s == 0) dq.addLast(p);
                else{
                    for(int y : g[p.getKey()]){
                        if(!vis[y]){
                            vis[y] = true;
                            dq.addLast(new Pair<>(y, p.getValue() * (1.0 / s)));
                        }
                    }
                }
            }
            step += 1;
            if(step == t) break;
        }
        while(!dq.isEmpty()){
            Pair<Integer, Double> p = dq.pollFirst();
            if(p.getKey() == target){
                return p.getValue();
            }
        }
        return 0.0;
    }
}

DFS递归(自顶向下 + 自底向上)

https://leetcode.cn/problems/frog-position-after-t-seconds/solution/dfs-ji-yi-ci-you-qu-de-hack-by-endlessch-jtsr/

既然答案是由若干分子为 1 的分数相乘得到,那么干脆只把分母相乘,最后再计算一下倒数,就可以避免因浮点乘法导致的精度丢失了。另外,整数的计算效率通常比浮点数的高。

  • 自顶向下是一边[递],一边把儿子个数 c 乘起来,如果能在第 t 秒到达 target,或者小于t 秒到达 target 且 target 是叶子节点(此时每次跳跃都会停留在原地) ,那么就记录答案为乘积的倒数,同时返回一个布尔值表示递归结束
  • **自底向上的思路是类似的,找到 target 后,在[归]的过程中做乘法。**个人更喜欢这种写法,因为只在找到 target 之后才做乘法,而自顶向下即使在不含 target 的子树中搜索,也会盲目地做乘法

技巧:
可以把节点 1 添加一个 0 号邻居,从而避免判断当前节点为根节点1,也避免了特判 n = 1的情况

此外,DFS 中的时间不是从 0 开始增加到 t,而是从 leftT = t 开始减小到 0,这样代码中只需和 0 比较,无需和 t 比较,从而减少一个DFS 之外变量的引入。

自顶向下:(递)

class Solution:
    def frogPosition(self, n: int, edges: List[List[int]], t: int, target: int) -> float:
        g = [[] for _ in range(n + 1)]
        g[1] = [0]  # 减少额外判断的小技巧
        for x, y in edges:
            g[x].append(y)
            g[y].append(x)  # 建树
        ans = 0

        def dfs(x: int, fa: int, left_t: int, prod: int) -> True:
            # t 秒后必须在 target(恰好到达,或者 target 是叶子停在原地)
            if x == target and (left_t == 0 or len(g[x]) == 1):
                nonlocal ans 
                ans = 1 / prod
                return True
            if x == target or left_t == 0: return False
            for y in g[x]: # 遍历 x 的儿子 y
                if y != fa and dfs(y, x, left_t-1, prod * (len(g[x]) - 1)):
                    return True # 找到 target 就不再递归了
            return False # 未找到target

        dfs(1, 0, t, 1)
        return ans    

自底向上:(归)

class Solution:
    def frogPosition(self, n: int, edges: List[List[int]], t: int, target: int) -> float:
        g = [[] for _ in range(n + 1)]
        g[1] = [0]  # 减少额外判断的小技巧
        for x, y in edges:
            g[x].append(y)
            g[y].append(x)  # 建树
        ans = 0

        def dfs(x: int, fa: int, left_t: int) -> True:
            # t 秒后必须在 target(恰好到达,或者 target 是叶子停在原地)
            if left_t == 0:
                return x == target
            if x == target:
                return len(g[x]) == 1
            for y in g[x]: # 遍历 x 的儿子 y
                if y != fa: 
                    prod = dfs(y, x, left_t-1) # 寻找 target
                    if prod:
                        return prod * (len(g[x]) - 1)  # 乘上儿子个数,并直接返回
            return 0 # 未找到target

        prod = dfs(1, 0, t)
        return 1 / prod if prod else 0

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

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

相关文章

一键呼叫可视对讲用于路灯杆

城市建设进入新时代&#xff0c;各种智慧化设施应运而生。路灯杆一键呼叫可视对讲系统可以实现智能安防、信息传递等多种功能&#xff0c;成为城市智慧化的重要组成部分。 1. 系统介绍 路灯杆一键呼叫可视对讲系统由路灯杆、摄像头、语音呼叫器等组成。当市民需要求助或报警时…

大数据开发之Hive案例篇5- count(distinct) 优化一例

文章目录 一. 问题描述二. 解决方案2.1 调整reduce个数2.2 SQL改写 一. 问题描述 需求: 卡在了reduce&#xff0c;只有一个reduce MR job卡在了最后一个reduce&#xff0c;任务迟迟未运行成功 二. 解决方案 2.1 调整reduce个数 一般一个reduce处理的数据是1G&#xff0c…

【Dubbo核心 详解四】Dubbo服务提供者的详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Dubbo核心详解(附代码示例) 文章目录 引言一、服务提供者1.1 服务提供者介绍Dubbo 服务提供者启…

NPDP|产品经理的硬实力体现在哪里?

在企业里&#xff0c;产品经理是一个具有综合职能的职位&#xff0c;其工作的范围可以说已经遍及到了公司的每个角落其接触的人员也涉及公司几乎所有的部门。 产品经理是产品品牌塑造者、更是营销骨干&#xff0c;是一套完善的营销运作制度&#xff0c;更是博大精深的营销操作…

git clone 报错10054,解决方法

使用git clone下载工程时&#xff0c;报错提示如下&#xff1a; fatal: unable to access https://github.com/deozhang/GaoZhongShuXue.git/: OpenSSL SSL_read: Connection was reset, errno 10054 报错提示的代码是10054&#xff0c;根据提示和网上搜索结果&#xff0c;可以…

Ae:跟踪运动

使用跟踪器 Tracker面板的跟踪运动 Track Motion功能&#xff0c;可通过手动添加和设置跟踪点来跟踪对象的运动&#xff0c;并能将获得的跟踪数据应用于其它对象。 Ae菜单&#xff1a;窗口/跟踪器 Tracker 点击跟踪器面板上的“跟踪运动”按钮&#xff0c;会为图层添加“动态跟…

Charles使用教程【简易版】

Charles抓包教程 1、电脑安装charles 2、电脑打开charles后安装root证书 3、电脑信任证书 4、手机连接与电脑同一wifi 5、设置手机代理 wlan设置中将当前 wifi 的代理改成手动&#xff0c;主机名填电脑 ip&#xff0c;端口填8888 此时如果当前手机是第一次被你的电脑设备代理或…

【JavaSE】Java基础语法(四)

文章目录 &#x1f37c;1. 循环细节&#x1f962;1.1 循环语句-dowhile循环&#x1f962;1.2 三种循环的区别&#x1f962;1.3 跳转控制语句 &#x1f37c;2. Random&#x1f962;2.1 Random产生随机数&#x1f962;2.2 Random练习-猜数字 &#x1f37c;1. 循环细节 &#x1f…

[资料分享]基于单片机防酒驾酒精检测报警系统装置设计、基于数字电路演讲计时protues仿真设计

基于单片机防酒驾酒精检测报警系统装置设计 一、说明 通过MQ3传感器检测酒精浓度&#xff0c;信号由ADCO832进行处理模数转化再到单片机进行处理&#xff0c;当检测到浓度超过“酒驾”报警值时&#xff0c;红灯亮起&#xff0c;当检测到浓度超过“醉驾”报警值时&#xff0c;…

网关网卡配置

Vmvare虚拟机设置外网IP 查看当前主机的网卡名/当前IP/子网掩码&#xff0c;网关地址 ifconfig route -n 查看DNS nslookup hcos 网卡名称为enp0s3&#xff0c;IP地址为10.0.2.15&#xff0c;子网掩码为255.255.255.0&#xff0c;网关为10.0.2.2&#xff1b; Centos设置IP/网…

【Java编程系列】gateway限流实践时发生的问题和解决方案

前期回顾&#xff1a; 【Java编程系列】Springcloud-gateway自带限流方案实践篇 1、实践中发生的问题 主要有以下几个问题&#xff1a; 1、限流返回的响应数据无法自定义 (LogFormatUtils.java:91) - [7b93af46-20] Completed 429 TOO_MANY_REQUESTS 返回后显示的情况如下&a…

C++第二章:变量和基本内置类型

变量和基本内置类型 一、基本内置类型1.1 算数类型1.2 带符号类型和无符号类型1.3 类型转换含有无符号类型的表达式 1.4 字面值常量整形和浮点型字面值字符和字符串字面值转义序列指定字面值的类型 二、变量2.1 变量的定义初始化列表初始化默认初始化 2.2 变量声明和定义的关系…

【web-ctf】ctf_BUUCTF_web(2)

文章目录 BUUCTF_webSQL注入1. [RCTF2015]EasySQL2. [CISCN2019 华北赛区 Day1 Web5]CyberPunk3. [CISCN2019 总决赛 Day2 Web1]Easyweb4. [GYCTF2020]Ezsqli5. [网鼎杯 2018]Comment 文件上传漏洞1. [WUSTCTF2020]CV Maker2. [NPUCTF2020]ezinclude3. [SUCTF 2019]EasyWeb 文件…

TADK 23.03 release note

主要功能概述&#xff1a; 基于深度学习的应用分类&#xff1a;在原有的基于机器学习的应用分类(AppID)能力基础上&#xff0c;扩展出新的深度学习参考模型和推理引擎。FFEL的raw byte特征提取&#xff1a;增加了流特征提取库(FFEL)对数据包中的raw byte特征提取能力&#xff0…

Meta AI 重磅推出LIMA!媲美GPT-4、无需RLHF就能对齐!

深度学习自然语言处理 原创作者&#xff1a;鸽鸽 昨天Meta AICMU这篇文章一出&#xff0c;twitter都炸了&#xff01; LIMA&#xff0c;只使用1000个精心挑选的样本微调一个 65B LLaMa&#xff0c;无需RLHF&#xff0c;性能媲美甚至优于GPT-4&#xff01; 论文&#xff1a;LIMA…

游戏洞察丨自来水还是井水,后流量时代的私域挑战

流量生意本质上是买卖用户浏览时间的生意&#xff0c;如果用户增长到顶&#xff0c;那就意味着供给到顶。对比 2021 年&#xff0c;2022 年的游戏出海在谷歌和 Facebook 上投入的广告成本几乎翻了一倍。新晋“渠道王者”TikTok 逐渐走进大家的视野。该现象背后的原因在于&#…

解决幂等问题,只需要记住这个口诀!

△Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 417 篇原创分享 作者 l Hollis 来源 l Hollis&#xff08;ID&#xff1a;hollischuang&#xff09; 作为开发人员&#xff0c;我们每天都要开发大量的接口&#xff0c;其中包括了读接口和写接口&#xff0c;而对于写接…

将矩阵按指定对角线转化为一个上三角矩阵numpy.triu()方法

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将矩阵按指定对角线转化为一个上三角矩阵 numpy.triu() 选择题 关于以下代码说法错误的一项是? import numpy as np a np.array([[1,2],[3,4]]) print("【显示】a\n",a) print(&…

应用程序和 API 攻击呈上升趋势

Akamai Technologies 发布了一份新的互联网现状报告&#xff0c;标题为“突破安全漏洞&#xff1a;针对组织的应用程序和 API 攻击的兴起”。 报告显示&#xff0c;亚太地区和日本&#xff08;APJ&#xff09;的金融服务业仍然是该地区受攻击最严重的行业&#xff0c;Web 应用…

大模型推理性能优化之KV Cache解读

0. 引言 做大模型性能优化的一定对KV Cache不陌生&#xff0c;那么我们对这个技术了解到什么程度呢&#xff1f;请尝试回答如下问题&#xff1a; KV Cache节省了Self-Attention层中哪部分的计算&#xff1f;KV Cache对MLP层的计算量有影响吗&#xff1f;KV Cache对block间的数据…