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)
java 复制代码
class Solution {
	//为了快速判断[u,v]对是否存在,连接成字符串List
    List<String> guess=new ArrayList<>();
    //记录以节点i为根,用户猜对的次数,当然由于在过程中进行了截断,所以最大值为k
    int[] 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;
    }
}
java 复制代码
//优化版本,但是还是超时
// 利用了如下的结论进行优化。
//基于已经计算出以 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月的每日一题了。😄

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

相关推荐
装不满的克莱因瓶6 分钟前
【Redis经典面试题十】热key与大key的问题如何解决?
java·数据库·redis·缓存·面试·面试题·key
武昌库里写JAVA7 分钟前
Redis奇幻之旅(四)4. Redis Cluster
java·开发语言·spring boot·学习·课程设计
唐僧洗头爱飘柔952710 分钟前
【Java基础】正则表达式的使用与常用类分享
java·开发语言·正则表达式·java基础·pattern·java se·java必备技能
lele_ne28 分钟前
【python】将字符串转换成整数类型
开发语言·python·算法
m0_7482571830 分钟前
【Spring】Spring实现加法计算器和用户登录
java·后端·spring
爱是小小的癌30 分钟前
Java-数据结构-链表-高频面试题(1)
java·数据结构·算法·链表
Atlim43 分钟前
maven多模块项目编译一直报Failure to find com.xxx.xxx:xxx-xxx-xxx:pom:1.0-SNAPSHOT in问题
java·开发语言·maven
敲代码养活全家44 分钟前
基于Elasticsearch8的向量检索实现相似图形搜索
java·elasticsearch
咔咔库奇1 小时前
HarmonyOS开发:传参方式
java·华为·harmonyos
ss2731 小时前
基于SpringBoot实现的保障性住房管理系统
java·spring boot·后端