2024.1.26力扣每日一题——边权重均等查询

2024.1.26

      • 题目来源
      • 我的题解
        • 方法一 使用dfs对每一组查询都求最近公共祖先(会超时,通不过)
        • 方法二 不需要构建图,直接在原始数组上进行求最大公共祖先的操作。

题目来源

力扣每日一题;题序:2846

我的题解

方法一 使用dfs对每一组查询都求最近公共祖先(会超时,通不过)

使用dfs对每一组查询都去找最近公共祖先,并在这个过程中统计边的权重,最后通过TreeMap计算出边权重集合中元素重复的最大次数,贪心策略可知,结果为:查询路径上总共的边-最大次数。

时间复杂度:O( n 2 n^2 n2)
空间复杂度:O( m × n m\times n m×n)

 List<Integer> list;
 public int[] minOperationsQueries(int n, int[][] edges, int[][] queries) {
     Map<Integer,Integer>[] graph=createGraph(n,edges);
     int qn=queries.length;
     int[] res=new int[qn];
     for(int i=0;i<qn;i++){
         int from=queries[i][0];
         int to=queries[i][1];
         if(from==to)
             continue;
         list=new ArrayList<>();
         boolean[] visited=new boolean[n];
         dfs(graph,from,to,visited,new ArrayList<>());
         res[i]=needChange(list);
     }
     return res;
 }
 public int needChange(List<Integer> l){
     TreeMap<Integer, Long> frequencyMap = new TreeMap<>(l.stream()
         .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())));
     TreeMap<Integer, Long> frequencySortMap=new TreeMap<>(Comparator.comparing(frequencyMap::get));
     frequencySortMap.putAll(frequencyMap);
     return l.size()-Integer.parseInt(frequencySortMap.get(frequencySortMap.lastKey()).toString());
     
}
 public Map<Integer,Integer>[] createGraph(int n,int[][] edges){
     Map<Integer,Integer>[] graph=new HashMap[n];
     for(int i=0;i<n;i++)
         graph[i]=new HashMap<>();
     for(int[] e:edges){
         int from =e[0];
         int to=e[1];
         int val=e[2];
         graph[from].put(to,val);
         graph[to].put(from,val);
     }
     return graph;
 }
 public void dfs(Map<Integer,Integer>[] graph,int from,int to,boolean[] visited,List<Integer> path){
     if(from==to){
         list=new ArrayList(path);
         return ;
     }
     visited[from]=true;
     for(int next:graph[from].keySet()){
         if(!visited[next]){
             path.add(graph[from].get(next));
             dfs(graph,next,to,visited,path);
             path.remove(path.size()-1);
         }
     }
     visited[from]=false;
 }
方法二 不需要构建图,直接在原始数组上进行求最大公共祖先的操作。

参考:官方题解

以节点 0 为根节点,使用数组 count[i]记录节点 i到根节点 0 的路径上边权重的数量,即 count[i][j] 表示节点 i到根节点 0 的路径上权重为 j的边数量。对于查询 queries[i]=[ a i a_i ai, b i b_i bi],记节点 l c a i lca_i lcai为节点 a i a_i ai b i b_i bi的最近公共祖先,那么从节点 a i a_i ai到节点 b i b_i bi的路径上,权重为 j 的边数量 t j t_j tj的计算如下:

t j = count [ a i ] [ j ] + count [ b i ] [ j ] − 2 × count [ lca i ] [ j ] t_j = \textit{count}[a_i][j] + \textit{count}[b_i][j] - 2 \times \textit{count}[\textit{lca}_i][j] tj=count[ai][j]+count[bi][j]2×count[lcai][j]
为了让节点 a i a_i ai到节点 b i b_i bi路径上每条边的权重都相等,贪心地将路径上所有的边都更改为边数量最多的权重即可,即从节点 a i a_i ai到节点 b i b_i bi路径上每条边的权重都相等所需的最小操作次数 r e s i ​ res_i​ resi的计算如下: res i = ∑ j = 1 W t j − max ⁡ 1 ≤ j ≤ W t j \textit{res}_i = \sum_{j=1}^{W}t_j - \max_{1 \le j \le W}t_j resi=j=1Wtjmax1jWtj
其中 W=26W = 26W=26 表示权重的最大值。

时间复杂度:O((m+n)×W+m×logn),其中 n 是节点数目,m 是查询数目,W 是权重的可能取值数目。
空间复杂度:O(n×W+m)

class Solution {
    static final int W = 26;

    public int[] minOperationsQueries(int n, int[][] edges, int[][] queries) {
        int m = queries.length;
        Map<Integer, Integer>[] neighbors = new Map[n];
        for (int i = 0; i < n; i++) {
            neighbors[i] = new HashMap<Integer, Integer>();
        }
        for (int[] edge : edges) {
            neighbors[edge[0]].put(edge[1], edge[2]);
            neighbors[edge[1]].put(edge[0], edge[2]);
        }
        List<int[]>[] queryArr = new List[n];
        for (int i = 0; i < n; i++) {
            queryArr[i] = new ArrayList<int[]>();
        }
        for (int i = 0; i < m; i++) {
            queryArr[queries[i][0]].add(new int[]{queries[i][1], i});
            queryArr[queries[i][1]].add(new int[]{queries[i][0], i});
        }

        int[][] count = new int[n][W + 1];
        boolean[] visited = new boolean[n];
        int[] uf = new int[n];
        int[] lca = new int[m];
        tarjan(0, -1, neighbors, queryArr, count, visited, uf, lca);
        int[] res = new int[m];
        for (int i = 0; i < m; i++) {
            int totalCount = 0, maxCount = 0;
            for (int j = 1; j <= W; j++) {
                int t = count[queries[i][0]][j] + count[queries[i][1]][j] - 2 * count[lca[i]][j];
                maxCount = Math.max(maxCount, t);
                totalCount += t;
            }
            res[i] = totalCount - maxCount;
        }
        return res;
    }

    public void tarjan(int node, int parent, Map<Integer, Integer>[] neighbors, List<int[]>[] queryArr, int[][] count, boolean[] visited, int[] uf, int[] lca) {
        if (parent != -1) {
            System.arraycopy(count[parent], 0, count[node], 0, W + 1);
            count[node][neighbors[node].get(parent)]++;
        }
        uf[node] = node;
        for (int child : neighbors[node].keySet()) {
            if (child == parent) {
                continue;
            }
            tarjan(child, node, neighbors, queryArr, count, visited, uf, lca);
            uf[child] = node;
        }
        for (int[] pair : queryArr[node]) {
            int node1 = pair[0], index = pair[1];
            if (node != node1 && !visited[node1]) {
                continue;
            }
            lca[index] = find(uf, node1);
        }
        visited[node] = true;
    }

    public int find(int[] uf, int i) {
        if (uf[i] == i) {
            return i;
        }
        uf[i] = find(uf, uf[i]);
        return uf[i];
    }
}

困难题果然不是我会做的,做做搬运工得了在这里插入图片描述

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据分享】1929-2023年全球站点的逐年平均能见度(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 之前我们分享过1929-2023年全球气象站点的逐年平均气温数据、逐年最高气温数据…

关于旋转编码器(EC11)的使用(判断旋转方向,按键处理)

关于旋转编码器(EC11)的使用&#xff08;判断旋转方向&#xff0c;按键处理&#xff09; 文章目录 关于旋转编码器(EC11)的使用&#xff08;判断旋转方向&#xff0c;按键处理&#xff09;零. 前言一. 注意事项二. 本文所述旋转编码器的旋转控制逻辑三. 旋转编码器判断代码&…

什么是S参数

S参数是网络参数&#xff0c;定义了反射波和入射波之间的关系&#xff0c;给定频率的S参数矩阵指定端口反射波b的矢量相对于端口入射波a的矢量&#xff0c;如下所示&#xff1a; bS∙a 在此基础上&#xff0c;如下图所示&#xff0c;为一个常见的双端口网络拓扑图&#xff1a;…

sqli.labs靶场(54-65关)

54、第五十四关 提示尝试是十次后数据库就重置&#xff0c;那我们尝试union 原来是单引号闭合 id-1 union select 1,database(),(select group_concat(table_name) from information_schema.tables where table_schemadatabase()) -- 数据库&#xff1a;challenges&#xff0c…

visio对任意形状进行任意角度旋转调整

在使用VISIO进行绘图时&#xff0c;可能需要对任意的形状进行旋转&#xff0c;让其达到一致。如下图所示&#xff0c;灰色矩形与直线要保持一致&#xff0c;而实际在绘制矩形时&#xff0c;成水平朝向。需要对矩形进行调整&#xff0c;将其与直线倾斜保持一致。具体步骤如下&am…

(已解决)vueQQ邮箱注册发送验证码前端设计,如何发送验证码设计倒计时

我们之前已经通过前端测试成功完成qq邮箱动态验证码发送&#xff08;未使用redis&#xff0c;我准备自己了解完后&#xff0c;后期有时间补上&#xff09; 衔接文章&#xff1a; 1&#xff1a; spingboot 后端发送QQ邮箱验证码 2&#xff1a; 这段代码建设图形化界面 <di…

双向链表的插入、删除、按位置增删改查、栈和队列区别、什么是内存泄漏

2024年2月4日 1.请编程实现双向链表的头插&#xff0c;头删、尾插、尾删 头文件&#xff1a; #ifndef __HEAD_H__ #define __HEAD_H__ #include<stdio.h> #include<stdlib.h> #include<string.h> typedef int datatype; enum{FALSE-1,SUCCSE}; typedef str…

RabbitMQ-2.SpringAMQP

SpringAMQP 2.SpringAMQP2.1.创建Demo工程2.2.快速入门2.1.1.消息发送2.1.2.消息接收2.1.3.测试 2.3.WorkQueues模型2.2.1.消息发送2.2.2.消息接收2.2.3.测试2.2.4.能者多劳2.2.5.总结 2.4.交换机类型2.5.Fanout交换机2.5.1.声明队列和交换机2.5.2.消息发送2.5.3.消息接收2.5.4…

文件夹正在使用无法删除(重命名)解决办法

1、问题描述 相信都遇到文件夹无法删除&#xff0c;或者无法重命名的情况。如果将文件夹正在使用的文件都已经关闭后&#xff0c;文件夹仍旧无法删除或重命名。 这个时候大概率是有隐藏的进程没有关闭&#xff0c;可以重启电脑&#xff0c;或者采用下面的方式关闭对应文件夹的…

小白水平理解面试经典题目LeetCode 20. Valid Parentheses【栈】

20.有效括号 小白渣翻译 给定一个仅包含字符 ‘(’ 、 ‘)’ 、 ‘{’ 、 ‘}’ 、 ‘[’ 和 ‘]’ &#xff0c;判断输入字符串是否有效。 输入字符串在以下情况下有效&#xff1a; 左括号必须由相同类型的括号封闭。 左括号必须按正确的顺序关闭。 每个右括号都有一个对…

vscode 突然连接不上服务器了(2024年版本 自动更新从1.85-1.86)

vscode日志 ll192.168.103.5s password:]0;C:\WINDOWS\System32\cmd.exe [17:09:16.886] Got some output, clearing connection timeout [17:09:16.887] Showing password prompt [17:09:19.688] Got password response [17:09:19.688] "install" wrote data to te…

uniapp踩坑之项目:简易版不同角色显示不一样的tabbar和页面

1. pages下创建三个不同用户身份的“我的”页面。 显示第几个tabbar&#xff0c;0是管理员 1是财务 2是司机 2. 在uni_modules文件夹创建底部导航cc-myTabbar文件夹&#xff0c;在cc-myTabbar文件夹创建components文件夹&#xff0c;在components文件夹创建cc-myTabbar.vue组件…

【机器学习】机器学习简单入门

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;matplotlib &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

【高质量精品】2024美赛C题高质量成品论文分享获取入口(后续会更新)

一定要点击文末的卡片&#xff0c;进入后&#xff0c;即可获取完整论文&#xff01;&#xff01; 首先&#xff0c;我们需要对缺失的 speed_mph 进行插补。缺失值处理是数据预处理的 重要环节之一。可以采用均值、中位数或者根据其他相关特征进行预测的方法来 填补缺失值。在这…

Packet Tracer - Configure IOS Intrusion Prevention System (IPS) Using the CLI

Packet Tracer - 使用CLI配置IOS入侵防御系统&#xff08;IPS&#xff09; 地址表 目标 启用IOS入侵防御系统&#xff08;IPS&#xff09;。 配置日志记录功能。 修改IPS签名规则。 验证IPS配置。 背景/场景 您的任务是在R1上启用IPS&#xff0c;扫描进入192.168.1.0网络…

Unity3d Cinemachine篇(完)— TargetGroup

文章目录 前言使用TargetGroup追随多个模型1. 创建二个游戏物体2. 创建TargetGroup相机3. 设置相机4. 完成 前言 上一期我们简单的使用了ClearShot相机&#xff0c;这次我们来使用一下TargetGroup 使用TargetGroup追随多个模型 1. 创建二个游戏物体 2. 创建TargetGroup相机 3…

刚刚晋升为管理者,还不会如何管理团队?你要重点关注这9个策略

管理团队需要明确团队目标、提前要求承诺、明确组织架构、团队高效协作、洞察员工、引入敏捷、执行可视化、及时反馈和复盘优化。 这样管理团队可以极大提高团队组织能力。团队组织能力强大的话&#xff0c;团队成员是可以实现自我管理的&#xff0c;会自我驱动去完成目标和执…

2024.2.5 vscode连不上虚拟机,始终waiting for server log

昨天还好好的&#xff0c;吃着火锅&#xff0c;做着毕设&#xff0c;突然就被vscode给劫了。 起初&#xff0c;哥们跟着网上教程有模有样地删除了安装包缓存&#xff0c;还删除了.vscode-server&#xff0c;发现没卵用&#xff0c;之前都是搜那个弹窗报错。 后来发现原来是vsco…

SpringBoot 全局异常处理

介绍 如果代码没有做异常处理&#xff0c;就会报框架错误&#xff0c;而这种格式不符合REST风格&#xff0c;也可以在每一个接口添加 try{ } catch { } 捕获异常&#xff0c;但是会非常的繁琐&#xff0c;这时候可以使用全局异常处理。 统一响应类 Data NoArgsConstructor …

掌握Linux du命令:高效查看文件和目录大小

今天我们在生产环境中的服务器上收到了有关/var磁盘目录使用率较高的警报。为了解决这一问题&#xff0c;我们进行了/var目录下一些大文件的清理和转移操作。在查找那些占用磁盘空间较多的文件时&#xff0c;我们频繁使用了du命令。在Linux系统中&#xff0c;du命令是一款功能强…