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=1Wtj−max1≤j≤Wtj
其中 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];}
}
困难题果然不是我会做的,做做搬运工得了
有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~
相关文章:

2024.1.26力扣每日一题——边权重均等查询
2024.1.26 题目来源我的题解方法一 使用dfs对每一组查询都求最近公共祖先(会超时,通不过)方法二 不需要构建图,直接在原始数组上进行求最大公共祖先的操作。 题目来源 力扣每日一题;题序:2846 我的题解 …...

C语言操作符超详细总结
文章目录 1. 操作符的分类2. 二进制和进制转换2.1 2进制转10进制2.1.1 10进制转2进制数字 2.2 2进制转8进制和16进制2.2.1 2进制转8进制2.2.2 2进制转16进制 3. 原码、反码、补码4.移位操作符4.1 左移操作符4.2 右移操作符 5. 位操作符:&、|、^、~6. 逗号表达式…...

【Java八股面试系列】JVM-内存区域
目录 Java内存区域 运行时数据区域 线程独享区域 程序计数器 Java 虚拟机栈 StackFlowError&OOM 本地方法栈 线程共享区域 堆 GCR-分代回收算法 字符串常量池 方法区 运行时常量池 HotSpot 虚拟机对象探秘 对象的创建 对象的内存布局 句柄 Java内存区域 运…...

计划任务功能优化,应用商店上架软件超过100款,1Panel开源面板v1.9.6发布
2024年2月7日,现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.9.6版本。 在v1.9.5和v1.9.6这两个小版本中,1Panel针对计划任务等功能进行了多项优化和Bug修复。此外,1Panel应用商店新增了3款应用,上架精选软件应用超过1…...
蓝桥杯(Web大学组)2023省赛真题3:收集帛书碎片
需要实现: 1.将二维数组转为一维数组; 2.数组去重 一、将二维数组转为一维数组: 二、数组去重: function collectPuzzle(...puzzles) {// console.log(puzzles);// console.log(...puzzles);// TODO:在这里写入具体的实现逻辑/…...

使用QT编写一个简单QQ登录界面
widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//设置窗口标题this->setWindowTitle("QQ");//设置窗口图标this->setWindowIcon(…...

TryHackMe-Net Sec Challenge练习
本文相关的TryHackMe实验房间链接:TryHackMe | Why Subscribe nmap nmap -T5 -p- 10.10.90.32 -T5 扫描速度 -p- 全端口扫描 答题: 这题叫我们找藏在http服务下的flag,根据上面扫出来的端口,所以我们开始搞80 这里简单介绍一下…...
面试 JavaScript 框架八股文十问十答第五期
面试 JavaScript 框架八股文十问十答第五期 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新! ⭐点赞⭐收藏⭐不迷路!⭐ 1)常见的位运算符有…...

[职场] 如何通过运营面试_1 #笔记#媒体#经验分享
如何通过运营面试 盈利是公司的事情,而用户就是你运营的事情。你需要彻底建立一个庞大而有效的用户群,这样才能让你们的公司想盈利就盈利,想战略就战略,想融资就融资。 一般从事运营的人有着强大的自信心,后台数据分析…...

CTFshow web(命令执行 41-44)
web41 <?php /* # -*- coding: utf-8 -*- # Author: 羽 # Date: 2020-09-05 20:31:22 # Last Modified by: h1xa # Last Modified time: 2020-09-05 22:40:07 # email: 1341963450qq.com # link: https://ctf.show */ if(isset($_POST[c])){ $c $_POST[c]; if(!p…...
XML介绍和基本语法
XML简介 XML(eXtensible Markup Language,可扩展标记语言)是一种用于标记电子文件使其具有结构性的标记语言。它允许用户定义自己的标记元素,使得信息的共享和数据的存储更加便捷和通用。XML广泛应用于Web开发、配置文件、数据交…...

Android:Android Studio安装及环境配置
1开发环境搭建 Android开发需要使用java的jdk环境,所以需要下载JAVA JDK。 1.1安装配置JAVA JDK Java的JDK下载: https://www.oracle.com/technetwork/java/javase/downloads/index.html 配置java的环境变量: JAVA_HOME:java安装路径。 新增环境变量CLASSPATH 在Path环境…...

力扣刷题之旅:进阶篇(三)
力扣(LeetCode)是一个在线编程平台,主要用于帮助程序员提升算法和数据结构方面的能力。以下是一些力扣上的入门题目,以及它们的解题代码。 --点击进入刷题地址 一、动态规划(DP) 首先,让我们来…...

代码随想录 Leetcode55. 跳跃游戏
题目: 代码(首刷自解 2024年2月9日): class Solution { public:bool canJump(vector<int>& nums) {int noz 0;for (int i nums.size() - 2; i > 0; --i) {if (nums[i] 0) {noz;continue;} else {if (nums[i] > noz) noz …...
Go Context -- 管理请求的上下文信息
在Go语言中,管理请求的上下文信息对于构建可靠的并发程序至关重要。context 包为我们提供了一种优雅的方式来传递请求的取消信号、超时信息和请求范围的值。接下来将深入探讨Go中的 context 包,包括其基本概念、用法、实际应用场景和最佳实践,…...

springboot170图书电子商务网站的设计与实现
简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计,课程设计参考与学习用途。仅供学习参考, 不得用于商业或者非法用途,否则,一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…...
设计模式(结构型模式)适配器模式
目录 一、简介二、使用2.1、目标接口2.2、被适配者2.3、适配器2.4、使用 一、简介 适配器模式是一种结构型设计模式,允许将一个类的接口转换成客户端所期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类能够协同工作。适配器模式通常用于连接两…...

计算机网络基本知识(二)
文章目录 概要分层为什么分层怎么分层?1.实体2.协议3.服务 分层基本原则正式认识分层详细例子解释 总结 概要 分层知识:概念理解 分层 为什么分层 大致以上五点 为了解决上面的问题(复杂) 大问题划分为小问题 怎么分层&#…...

158基于matlab的用于分析弧齿锥齿轮啮合轨迹的程序
基于matlab的用于分析弧齿锥齿轮啮合轨迹的程序,输出齿轮啮合轨迹及传递误差。程序已调通,可直接运行。 158 matlab 弧齿锥齿轮啮合轨迹 传递误差 (xiaohongshu.com)...

C#中的浅度和深度复制(C#如何复制一个对象)
文章目录 浅度和深度复制浅度复制深度复制如何选择 浅度和深度复制 在C#中,浅度复制(Shallow Copy)和深度复制(Deep Copy)是两种不同的对象复制方式,满足不同的应用场景需求,它们主要区别在于处…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...