当前位置: 首页 > news >正文

2024.2.29力扣每日一题——统计可能的树根数目

2024.2.29

      • 题目来源
      • 我的题解
        • 方法一 深度搜索(暴力) 超时
        • 方法二 树形动态规划

题目来源

力扣每日一题;题序:2581

我的题解

方法一 深度搜索(暴力) 超时
  1. 以每个节点node为跟进行深度搜索,并在搜索过程中记录前驱节点,然后判断[前驱节点,当前节点]是否在guesses中出现。若出现,则表示Bob猜测对一次,并记录在count数组中。最后遍历count数组,看有多少满足count[i]>=k。该值就是可能成为树根的 节点数目

时间复杂度:O( n ( n + e ) n(n+e) n(n+e))。n表示树的节点数,e表示树的边数
空间复杂度:O(n)

class Solution {//为了快速判断[u,v]对是否存在,连接成字符串ListList<String> guess=new ArrayList<>();//记录以节点i为根,用户猜对的次数,当然由于在过程中进行了截断,所以最大值为kint[] count;public int rootCount(int[][] edges, int[][] guesses, int k) {int n=edges.length+1;count=new int[n];List<Integer>[] g=createGraph(n,edges);for(int[] t:guesses){int u = t[0];int v = t[1];guess.add(u+"-"+v);}for(int i=0;i<n;i++){dfs(i,i,g,-1,k);}int res=0;for(int i=0;i<n;i++){if(count[i]>=k)res++;}return res;}//深度优先搜索public void dfs(int root,int cur,List<Integer>[] g,int pre,int k){//根节点没有父节点if(pre!=-1){String t=pre+"-"+cur;//Bob猜测正确if(guess.contains(t))count[root]++;//截断,当已经正确的次数达到k,表明以root为根一定满足if(count[root]>=k)return;}for(int next:g[cur]){//防止循环遍历if(next!=pre){dfs(root,next,g,cur,k);}}}//构建树public List<Integer>[] createGraph(int n,int[][] edges){List<Integer>[] g=new ArrayList[n];for(int i=0;i<n;i++){g[i]=new ArrayList<>();}for(int[] t:edges){int from=t[0];int to = t[1];g[from].add(to);g[to].add(from);}return g;}
}
//优化版本,但是还是超时
// 利用了如下的结论进行优化。
//基于已经计算出以 x 为树根时猜对的次数,很容易就可以计算出以 y 为树根时猜对的次数:
//如果 (x,y) 存在于 guesses,猜对次数减一;
//如果 (y,x) 存在于 guesses,猜对次数加一。class Solution {List<String> guess=new ArrayList<>();int cnt=0;int res=0;public int rootCount(int[][] edges, int[][] guesses, int k) {int n=edges.length+1;// count=new int[n];List<Integer>[] g=createGraph(n,edges);for(int[] t:guesses){int u = t[0];int v = t[1];guess.add(u+"-"+v);}dfs(0,0,g,-1,k);rdfs(g,0,-1,k,cnt);return res;}public void rdfs(List<Integer>[] g,int x,int t,int k,int cnt){if(cnt>=k){res++;}for(int y:g[x]){if(t==y)continue;rdfs(g,y,x,k,cnt-(guess.contains(x+"-"+y)?1:0)+(guess.contains(y+"-"+x)?1:0));}}public void dfs(int root,int cur,List<Integer>[] g,int pre,int k){if(pre!=-1){String t=pre+"-"+cur;if(guess.contains(t))cnt++;}for(int next:g[cur]){if(next!=pre){dfs(root,next,g,cur,k);}}}public List<Integer>[] createGraph(int n,int[][] edges){List<Integer>[] g=new ArrayList[n];for(int i=0;i<n;i++){g[i]=new ArrayList<>();}for(int[] t:edges){int from=t[0];int to = t[1];g[from].add(to);g[to].add(from);}return g;}
}
方法二 树形动态规划

看官方题解吧,弄不明白

终于补完2月的每日一题了。😄

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

http://www.lryc.cn/news/330754.html

相关文章:

  • 同一个主机配置多个SSH key
  • SAP系统财务模块简介:实现财务管理的卓越之道
  • 【pytest】功能特性及常用插件
  • 基于SpringBoot和Vue的房产销售系统的设计与实现
  • ROS2从入门到精通1-2:详解ROS2服务通信机制与自定义服务
  • vue两个特性和什么是MVVM
  • CAD Plant3D 2023 下载地址及安装教程
  • 集成电路企业tapeout,如何保证机台数据准确、完整、高效地采集?
  • Nginx三大常用功能“反向代理,负载均衡,动静分离”
  • 类方法介绍、使用细节
  • Java SpringBoot中优雅地判断一个对象是否为空
  • 算法——矩阵:对于边界元素的处理
  • Git分支提交时自动大写 fatal: the remote end hung up unexpectedly
  • 隐私计算实训营第七讲-隐语SCQL的架构详细拆解
  • Android JNI开发定义全局变量
  • docker容器部署gitlab的runner的shell模式注册下job中无法使用docker指令
  • 【SpringCloud】Zuul网关中心 代码详细介绍
  • Delphi D12中实现安卓中文语音合成(中文朗读)不用第三方控件
  • 设计模式 - Provider 模式
  • R语言颜色细分
  • 面向返回编程ROP问题及挑战
  • vscode shadertoy插件,非常方便的glsl着色器编写工具
  • 网络请求避坑,私有网络请求(Private Network Access)
  • AVL树和红黑树
  • 多线程入门
  • #!/bin/sh和#!/bin/bash的区别
  • 腾讯云(CVM)托管进行权限维持
  • STM32-03基于HAL库(CubeMX+MDK+Proteus)输入检测案例(按键控制LED)
  • DS3231SN
  • tsconfig.json文件翻译