LeetCode 1782.统计点对的数目

给你一个无向图,无向图由整数 n ,表示图中节点的数目,和 edges 组成,其中 edges[i] = [ui, vi] 表示 ui 和 vi 之间有一条无向边。同时给你一个代表查询的整数数组 queries 。

第 j 个查询的答案是满足如下条件的点对 (a, b) 的数目:

a < b
cnt 是与 a 或者 b 相连的边的数目,且 cnt 严格大于 queries[j] 。
请你返回一个数组 answers ,其中 answers.length == queries.length 且 answers[j] 是第 j 个查询的答案。

请注意,图中可能会有 多重边 。

示例 1:
在这里插入图片描述
输入:n = 4, edges = [[1,2],[2,4],[1,3],[2,3],[2,1]], queries = [2,3]
输出:[6,5]
解释:每个点对中,与至少一个点相连的边的数目如上图所示。
answers[0] = 6。所有的点对(a, b)中边数和都大于2,故有6个;
answers[1] = 5。所有的点对(a, b)中除了(3,4)边数等于3,其它点对边数和都大于3,故有5个。
示例 2:

输入:n = 5, edges = [[1,5],[1,5],[3,4],[2,5],[1,3],[5,1],[2,3],[2,5]], queries = [1,2,3,4,5]
输出:[10,10,9,8,6]

提示:

2 <= n <= 2 * 104^44
1 <= edges.length <= 105^55
1 <= ui, vi <= n
ui != vi
1 <= queries.length <= 20
0 <= queries[j] < edges.length

法一:我们可以先把每个点的度计算出来,然后对于一个查询,它要求连接两点之一的边数大于一个值q,我们就可以把每个点的度排序,然后相向双指针计算出两点度之和大于q的点对数,但这样计算可能会多算重复值,比如示例1中的边12和边21,这两条边计算出来点1和点2的度都是2,两者相加就是4,但其实只有2条边,我们需要用两个点的度4减去相同的边的数量2,如果减少2后的值小于等于q,则答案需要减去1对点对:

class Solution {
public:vector<int> countPairs(int n, vector<vector<int>>& edges, vector<int>& queries) {// 保存每个点的度vector<int> deg(n + 1);// 保存两点间的边数unordered_map<int, int> cntEdge;for (vector<int> &edge : edges) {int x = edge[0];int y = edge[1];++deg[x];++deg[y];if (x > y) {swap(x, y);}// 可以用一个int保存两个值小于等于65535的数// 这里表示从x到y的边数增加1++cntEdge[x << 16 | y];}vector<int> sortedDeg = deg;sort(sortedDeg.begin(), sortedDeg.end());vector<int> ans(queries.size());for (int i = 0; i < queries.size(); ++i) {int left = 1;int right = n;while (left < right) {if (sortedDeg[left] + sortedDeg[right] > queries[i]) {ans[i] += right - left;--right;} else {++left;}}for (auto [k, c] : cntEdge) {int x = k >> 16;int y = k & 0xffff;// 如果点x和点y的度之和大于查询目标值,说明该点对计入了答案// 如果减去相同的边数后不大于查询目标值了,说明该点对不应计入答案if (deg[x] + deg[y] > queries[i] && deg[x] + deg[y] - c <= queries[i]) {--ans[i];}}}return ans;}
};

如果edges的长度为m,queries的长度为q,则此算法时间复杂度为O(nlogn + q(n + m)),空间复杂度为O(n+m),cntEdge的长度最多为m。

法二:我们可以构建一个数组,该数组的key为与点对相连的边的数量,value为有多少个点对相连的边的数量为key,这样对于某个查询q,答案就是数组下标大于q的所有元素和,即用后缀和来获得答案:

class Solution {
public:vector<int> countPairs(int n, vector<vector<int>>& edges, vector<int>& queries) {// 用时O(n)vector<int> deg(n + 1);unordered_map<int, int> cntEdge;// 用时O(m)for (vector<int> &edge : edges) {int x = edge[0];int y = edge[1];++deg[x];++deg[y];if (x > y) {swap(x, y);}++cntEdge[x << 16 | y];}// key为度,value为度为key的点数unordered_map<int, int> degToNum;// 用时O(n)for (int i = 1; i < deg.size(); ++i) {++degToNum[deg[i]];}int maxDeg = *max_element(deg.begin() + 1, deg.end());int k = maxDeg * 2 + 2;// key为与点对相连的边的数量,value为点对相连的边数为key的点对数量vector<int> degCnt(k);// 暴力计算任意两点的度数和,并将度数和填入degCnt,计算后degCnt会包含重复边// 如果边的数量为m,这里的时间复杂度为m// 因为平均情况下假设有x种度数,则度数和为1+2+3+...+x=(1+x)x/2// 而度数和有2m个,因此x平均值为根号(4m),两重循环的平均时间就是O(m)for (auto [deg1, cnt1] : degToNum) {for (auto [deg2, cnt2] : degToNum) {// 为避免重复计算,只计算deg1<=deg2的情况// 如果是小于// 例如degToNum为[0,2,3],表示度为1的有2个点,度为2的有3个点// deg1为1,deg2为2,此时度的和为5的点对数中,deg1和deg2贡献了2*3个if (deg1 < deg2) {degCnt[deg1 + deg2] += cnt1 * cnt2;// 如果是等于// 例如度为3的点有4个,那么度的和为6的点对数中,deg1和deg2两两配对// 贡献了cnt1 * (cnt1 - 1) / 2个} else if (deg1 == deg2) {degCnt[deg1 + deg2] += (cnt1 - 1) * cnt1 / 2;}}}// 去除重复边,如果点对间有num个边,说明该点对数实际与这两点相连的边数为s-num// 即度的和为s的两点实际相连的边数为s-num// 用时最大O(m)for (auto [edge, num] : cntEdge) {int s = deg[edge >> 16] + deg[edge & 0xffff];++degCnt[s - num];--degCnt[s];}// 计算后缀和// 用时O(m),因为对于所有的点,每个点最多有m个度for (int i = k - 1; i > 0; --i) {degCnt[i - 1] += degCnt[i];}// 计算每个查询的结果,查询为q时,degCnt[q]为大于等于q的点对数// 在q只能取整数的情况下,degCnt[q+1]即为大于q的点对数// 超出索引时,查询的答案为0// 此处我们用两倍的最大度数加1表示超出索引// 上面双重循环中,degCnt中最大key就是两个最大度的和// 用时O(q)for (int &q : queries) {q = degCnt[min(q + 1, k - 1)];}return queries;}
};

此算法时间复杂度为O(n+m+q),空间复杂度为O(n+m)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

U-Mail邮件系统-全面适配信创环境的国产邮件系统

在当今数字化时代&#xff0c;邮件系统作为企业、政府机构以及各类组织日常办公不可或缺的沟通工具&#xff0c;其安全性、稳定性以及自主可控性的重要性日益凸显。随着信创产业的蓬勃发展&#xff0c;国产邮件系统应运而生&#xff0c;成为保障信息安全、推动数字化转型的关键…

【LeetCode 热题 100】394. 字符串解码

Problem: 394. 字符串解码 给定一个经过编码的字符串&#xff0c;返回它解码后的字符串。 编码规则为: k[encoded_string]&#xff0c;表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的&#xff1b;输入字符串中没有…

Activity之间互相发送数据

activity_send_data_req.xml<?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_pare…

设计模式:访问者模式 Visitor

目录前言问题解决方案结构代码前言 访问者是一种行为设计模式&#xff0c;它能将算法与其所作用的对象隔离开来。 问题 假如你的团队开发了一款能够使用巨型图像中地理信息的应用程序。 图像中的每个节点既能代表复杂实体&#xff08;例如一座城市&#xff09;&#xff0c; 也…

OpenCV 学习探秘之四:从角点检测,SIFT/SURF/ORB特征提取,目标检测与识别,Haar级联分类人脸检测,再到机器学习等接口的全面实战应用与解析

书接上回&#xff0c;前面介绍了一些基本应用&#xff0c;本篇则着重介绍一些比较复杂的应用。 附&#xff1a;本文所用例子中使用的Opencv库OpenCV4.5.4版本编译好的库 五、特征提取与描述 5.1 角点检测&#xff1a;Harris 角点和 Shi-Tomasi 角点 5.1.1 Harris 角点检测&a…

《秋招在即!Redis数据类型面试题解析》

博客主页&#xff1a;天天困啊系列专栏&#xff1a;面试题关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Redis中常见的基础数据结构总共五种&#xff1a;这五种类型分别为String&#xff…

政务网站内容检测系统对错敏信息有什么作用

政务网站内容检测系统在错敏信息管理中发挥着重要作用&#xff0c;能够有效提升政府网站的信息安全性与合规性。以下从错敏信息的作用及蚁巡政务信息巡查系统的功能特点两方面进行说明。一、政务网站内容检测系统对错敏信息的作用1、实时监测与识别内容检测系统通过智能化技术对…

Tower of Hanoi 汉诺塔

题目描述The Tower of Hanoi game consists of three stacks (left, middle and right) and n round disks of different sizes. Initially, the left stack has all the disks, in increasing order of size from top to bottom. The goal is to move all the disks to the r…

在 Docker 中启动 Nginx 并挂载配置文件到宿主机目录

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 在 Docker 中启动 Nginx 并挂载配置文件到宿主机目录前言一、创建宿主机目录存放 Nginx 配置1.1 在宿主机&#xff08;如 Windows 或 Linux&#xff09;上创建目录&#xff0…

认识ansible(入门)

什么是ansible&#xff1f;Ansible是一款自动化运维工具&#xff0c;基于Python开发&#xff0c;集合了众多运维工具&#xff08;puppet、cfengine、chef、func、fabric&#xff09;的优点&#xff0c;实现了批量系统配置、批量程序部署、批量运行命令等功能。Ansible是基于模块…

Apache Ignite 关于 **Executor Service(执行器服务)** 的介绍

这段内容是 Apache Ignite 关于 Executor Service&#xff08;执行器服务&#xff09; 的介绍。我们可以把它理解为&#xff1a;一个分布式的“线程池”&#xff0c;可以把任务分发到集群中的多个节点上去执行。 下面我用通俗易懂的方式帮你彻底理解这个概念。&#x1f310; 什…

应用Builder模式在C++中进行复杂对象构建

引言 在软件开发中&#xff0c;构建复杂对象时常常会遇到构造函数或setter方法过于复杂的情况。Builder模式作为一种创建型设计模式&#xff0c;能够有效地解决这一问题。Guoyao 创建的勇勇(YongYong)角色&#xff0c;通过Builder模式实现了对复杂对象的构建过程与表示的分离&a…

gradio作为原型工具

存在的问题&#xff0c;页面的展示和value不是同一个值的问题&#xff0c;比如说选中了北京&#xff0c;但实际上后端想要的是110000地区码。 在实际开发中&#xff0c;前端展示给用户的是可读的地区名称&#xff08;如“北京”&#xff09;&#xff0c;而背后处理时通常需要的…

计算声子谱

准备的还是vasp的必备文件&#xff1a;POSCAR POTCAR KPOINTS&#xff0c;剩下需要的INCAR、band文件下面代码可以生成&#xff1a;#!/bin/bash if [ ! -f band.conf ];then cat >>band.conf <<EOF ATOM_NAME Ti Al B DIM 1 1 1 BAND 0.0 0.0 0.0 0.5 -0.5 0.5…

深度学习 目标检测常见指标和yolov1分析

目录 一、常见指标 1、IoU 2、Confidence置信度 3、精准度和召回率 4、mAP 5、NMS方法 6、检测速度 前传耗时 FPS 7、FLOPs 二、YOLOv1 检测流程 1、图像网格划分 2、类别预测 3、输出张量 损失函数 优点 缺点 如题&#xff0c;这篇介绍一下目标检测中常见的…

31. 伪类和伪元素区别

总结 选择对象不同内容说明伪类作用对象元素的状态或位置伪元素作用对象元素的一部分内容或虚拟内容是否新增节点均不新增节点常用符号:&#xff08;伪类&#xff09;、::&#xff08;伪元素&#xff09;推荐场景伪类用于交互与状态控制&#xff1b;伪元素用于样式修饰与内容插…

ChatGPT、Playground手动模拟Agent摘要缓冲混合记忆功能

01. 摘要缓冲混合记忆 摘要缓冲混合记忆中&#xff0c;所需的模块有&#xff1a; chat_message_history&#xff1a;存储历史消息列表。moving_summary_buffer&#xff1a;移除消息的汇总字符串。summary_llm&#xff1a;生成摘要的 LLM&#xff0c;接收 summary&#xff08;…

全国青少年信息素养大赛(无人飞行器主题赛(星际迷航)游记)

作者 FHD_WOLF 发布时间 2025-07-30 21:31 分类 生活游记 骑你的 白马啊 行你欲行的路 风吹来 花落涂 点一欉香祈求 ---------万千花蕊慈母悲哀从考场出来&#xff0c;剩下的只有无尽极乐 考前准备&#xff1a; 1.电脑充电。 &#xff08;这个赛项需要自带设备&#x…

Kubernetes (K8s) 部署资源的完整配置OceanBase

Kubernetes Deployment 配置&#xff08;oceanbase-deployment.yaml&#xff09; # oceanbase-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata:name: oceanbase-deployment spec:replicas: 1selector:matchLabels:app: oceanbasetemplate:metadata:labels:app…

ACS-电机控制Buffer-任意路径规划(PVSPLINE绘制圆形)

该程序是一个双轴运动&#xff0c;绘制圆形 原始程序&#xff08;可以直接使用&#xff09; GLOBAL INT X1,Y1,ii GLOBAL REAL MY_ARRAY(4)(12) GLOBAL REAL piX1 0; Y1 1 ! Axis assignment pi ACOS(-1) ! Shortcut for generating piii 0 LOOP 12MY_ARRAY(0)(ii) COS(…