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月的每日一题了。😄

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

相关推荐
DKPT几秒前
Java享元模式实现方式与应用场景分析
java·笔记·学习·设计模式·享元模式
✿ ༺ ོIT技术༻4 分钟前
剑指offer第2版:动态规划+记忆化搜索
算法·动态规划·记忆化搜索
Percep_gan8 分钟前
idea的使用小技巧,个人向
java·ide·intellij-idea
缘来是庄9 分钟前
设计模式之迭代器模式
java·设计模式·迭代器模式
Liudef0615 分钟前
基于HTML与Java的简易在线会议系统实现
java·前端·html
JosieBook25 分钟前
【Java编程动手学】Java常用工具类
java·python·mysql
oioihoii28 分钟前
C++11标准库算法:深入理解std::none_of
java·c++·算法
老虎06271 小时前
数据结构(Java)--位运算
java·开发语言·数据结构
yanjiaweiya1 小时前
云原生-集群管理续
java·开发语言·云原生
Swift社区1 小时前
Swift 解 LeetCode 320:一行单词有多少种缩写可能?用回溯找全解
开发语言·leetcode·swift