当前位置: 首页 > news >正文

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];}
}

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

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

相关文章:

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

2024.1.26 题目来源我的题解方法一 使用dfs对每一组查询都求最近公共祖先&#xff08;会超时&#xff0c;通不过&#xff09;方法二 不需要构建图&#xff0c;直接在原始数组上进行求最大公共祖先的操作。 题目来源 力扣每日一题&#xff1b;题序&#xff1a;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. 位操作符&#xff1a;&、|、^、~6. 逗号表达式…...

【Java八股面试系列】JVM-内存区域

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

计划任务功能优化,应用商店上架软件超过100款,1Panel开源面板v1.9.6发布

2024年2月7日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.9.6版本。 在v1.9.5和v1.9.6这两个小版本中&#xff0c;1Panel针对计划任务等功能进行了多项优化和Bug修复。此外&#xff0c;1Panel应用商店新增了3款应用&#xff0c;上架精选软件应用超过1…...

蓝桥杯(Web大学组)2023省赛真题3:收集帛书碎片

需要实现&#xff1a; 1.将二维数组转为一维数组&#xff1b; 2.数组去重 一、将二维数组转为一维数组&#xff1a; 二、数组去重&#xff1a; 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实验房间链接&#xff1a;TryHackMe | Why Subscribe nmap nmap -T5 -p- 10.10.90.32 -T5 扫描速度 -p- 全端口扫描 答题&#xff1a; 这题叫我们找藏在http服务下的flag&#xff0c;根据上面扫出来的端口&#xff0c;所以我们开始搞80 这里简单介绍一下…...

面试 JavaScript 框架八股文十问十答第五期

面试 JavaScript 框架八股文十问十答第五期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01;关注专栏后就能收到持续更新&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;常见的位运算符有…...

[职场] 如何通过运营面试_1 #笔记#媒体#经验分享

如何通过运营面试 盈利是公司的事情&#xff0c;而用户就是你运营的事情。你需要彻底建立一个庞大而有效的用户群&#xff0c;这样才能让你们的公司想盈利就盈利&#xff0c;想战略就战略&#xff0c;想融资就融资。 一般从事运营的人有着强大的自信心&#xff0c;后台数据分析…...

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&#xff08;eXtensible Markup Language&#xff0c;可扩展标记语言&#xff09;是一种用于标记电子文件使其具有结构性的标记语言。它允许用户定义自己的标记元素&#xff0c;使得信息的共享和数据的存储更加便捷和通用。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环境…...

力扣刷题之旅:进阶篇(三)

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

代码随想录 Leetcode55. 跳跃游戏

题目&#xff1a; 代码(首刷自解 2024年2月9日&#xff09;&#xff1a; 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语言中&#xff0c;管理请求的上下文信息对于构建可靠的并发程序至关重要。context 包为我们提供了一种优雅的方式来传递请求的取消信号、超时信息和请求范围的值。接下来将深入探讨Go中的 context 包&#xff0c;包括其基本概念、用法、实际应用场景和最佳实践&#xff0c…...

springboot170图书电子商务网站的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…...

设计模式(结构型模式)适配器模式

目录 一、简介二、使用2.1、目标接口2.2、被适配者2.3、适配器2.4、使用 一、简介 适配器模式是一种结构型设计模式&#xff0c;允许将一个类的接口转换成客户端所期望的另一个接口&#xff0c;使得原本由于接口不兼容而不能一起工作的类能够协同工作。适配器模式通常用于连接两…...

计算机网络基本知识(二)

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

158基于matlab的用于分析弧齿锥齿轮啮合轨迹的程序

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

C#中的浅度和深度复制(C#如何复制一个对象)

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

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...