dengch

 

LeetCode370

1.找到冠军I

题目概述:给定一个二维数组grid,grid[i][j] = 0表示i输给j,grid[i][j] = 1表示j输给i。求冠军队伍。冠军队伍的定义:如果不存在强于该队伍的队伍,那么这支队伍就是冠军队伍
解题思路:由于本题一定有解,所以我们只需统计每支队伍的赢的数量,再从中选出赢得最多的队伍即可
时间复杂度\(O(n^2)\)
代码

class Solution {
    public int findChampion(int[][] grid) {
        int n = grid.length;
        int team[] = new int[n];
        
        for(int i = 0; i < n; i ++){
            for(int j = 0; j < n; j ++){
                if(i == j)continue;
                else{
                    if(grid[i][j] == 1)team[i]++;
                    else team[j]++;
                }
            }
        }
        
        int res = -1,ma = -1;
        for(int i = 0; i < n; i ++){
            if(team[i] > ma){
                ma = team[i];
                res = i;
            }
        }
        
        return res;
    }
}

2.找到冠军Ⅱ

题目概述:给定队伍数量n和一个二维数组edges,edges[i] = (u,v).表示节点u和节点v之间有边,也表示j队伍输给u队伍,这个图是有向无环图。如果根据这些信息能够确定一支冠军队伍,则输出冠军队伍的编号,否则输出-1。冠军队伍的定义:如果不存在强于该队伍的队伍,那么这支队伍就是冠军队伍
解题思路:由于是有向无环图,并且根据其冠军队伍的定义,我们只要统计入度为0的节点的数量。如果数量为1,表示冠军队伍只有一支,输出答案,否则输出-1.
时间复杂度\(O(n)\)
代码

class Solution {
    public int findChampion(int n, int[][] edges) {
        int du[] = new int[n];
        
        for(int e[] : edges){
            int a = e[0],b = e[1];
            du[b]++;
        }
        
        int res = -1,count = 0;
        for(int i = 0; i < n; i ++){
            if(du[i] == 0){
                res = i;
                count++;
            }
        }
        
        if(count > 1)res = -1;
        
        return res;
    }
}

3.在树上执行操作以后得到的最大分数

题目概述:有一棵树,每个节点有不同的值,你可以选择任意数量的节点,并获得该节点的分数,该节点的值变为0.问:你能获得的最大分数是多少,前提:保证这棵树是一棵健康树。
健康树:根节点到任意一个叶子节点的路径上的节点之和不为0
解题思路:这道题,我们需要注意一个细节:这些节点的值都是大于0的正整数(根据数据范围可得)。也就是说,想要保证这棵树健康,只需保证每条路径上至少有一个点不被选。很容易发现该问题由许多子问题组成:如果不选当前节点,那么可以获得其所有子节点的数值;如果选择当前节点,就要从其子节点中选一个作为不被选择(使路径之和不为0).如果从正面入手,我们需要维护所有子树的和以及节点的选与不选,比较繁琐。但如果,我们从反面入手,先假设所有点都选上,再从中挑选出使答案最大的方案。只需维护节点的选与不选
时间复杂度\(O(n)\)
代码

class Solution {
    public long maximumScoreAfterOperations(int[][] edges, int[] values) {
        long sum = 0;
        int n = values.length;
        for(int i = 0; i < n; i ++)sum += values[i];

        //construct the undirected graph
        Map<Integer,List<Integer>>map = new HashMap<>();
        for(int i = 0; i < n - 1; i ++){
            int a = edges[i][0],b = edges[i][1];
            List<Integer>list = map.getOrDefault(a,new ArrayList<>());
            List<Integer>list2 = map.getOrDefault(b,new ArrayList<>());
            list.add(b);
            list2.add(a);
            map.put(a,list);
            map.put(b,list2);
        }

        long loss = dfs(map,values,0,-1);

        return sum - loss;
    }

    //return the minimum loss of x's subtrees
    public long dfs(Map<Integer,List<Integer>>map,int values[],int x,int fa){
        //if x is the leave,we can nor choise x,otherwise,the tree is unhealthy
        if(x != 0 && map.get(x).size() == 1)return values[x];
        //not choise x
        long loss1 = values[x],loss2 = 0;
        //choise x
        List<Integer>list = map.get(x);
        for(Integer t : list){
            if(t == fa)continue;
            else{
                loss2 += dfs(map,values,t,x);
            }
        }

        return Math.min(loss1,loss2);
    }
}

posted on 2023-11-05 19:25  BkDench  阅读(15)  评论(0)    收藏  举报

导航