初学python记录:力扣928. 尽量减少恶意软件的传播 II

题目:

给定一个由 n 个节点组成的网络,用 n x n 个邻接矩阵 graph 表示。在节点网络中,只有当 graph[i][j] = 1 时,节点 i 能够直接连接到另一个节点 j

一些节点 initial 最初被恶意软件感染。只要两个节点直接连接,且其中至少一个节点受到恶意软件的感染,那么两个节点都将被恶意软件感染。这种恶意软件的传播将继续,直到没有更多的节点可以被这种方式感染。

假设 M(initial) 是在恶意软件停止传播之后,整个网络中感染恶意软件的最终节点数。

我们可以从 initial删除一个节点并完全移除该节点以及从该节点到任何其他节点的任何连接。

请返回移除后能够使 M(initial) 最小化的节点。如果有多个节点满足条件,返回索引 最小的节点

提示:

  • n == graph.length
  • n == graph[i].length
  • 2 <= n <= 300
  • graph[i][j]01.
  • graph[i][j] == graph[j][i]
  • graph[i][i] == 1
  • 1 <= initial.length < n
  • 0 <= initial[i] <= n - 1
  • initial 中每个整数都不同

思考:

今天的题和昨天的很相似,区别在于:"从 initial 中删除一个节点 = 完全移除该节点 以及从该节点到任何其他节点的任何连接"

相似的,仍然将图中所有彼此有路径到达的节点们看成一组,如果一组中有至少一个节点初始时被感染,那么这一组所有节点最后都会被感染。

我们要去掉initial中的一个节点和它的所有边之后,使剩下的感染节点最少 ----> 这个节点能且只能凭自己感染的节点最多(1. 通过其他initial节点连接的节点不算 2. 被多个initial节点感染的节点不算)

那么我们的算法步骤如下,数组visited 记录每个节点能被多少initial节点凭自己感染("≥0"表示唯一的initial节点索引;"-2"表示有多个initial节点连接);字典sum_dict记录initial节点能且只能凭自己感染的节点数:

1. 遍历initial中的每个节点node。

2. 找到所有和node之间有路径的节点k,并进行判断:1. 若visitedk为-1,则将visitedk设为node;2. 若visitedk为大于等于0的值,说明此前已经有initial节点感染他了,则将visitedk设为-2.

3. initial中的每个节点node都判断完后,遍历visited数组,若值大于等于0,则说明这个节点只被一个initial节点感染了,将字典sum_dict中该initial节点对应的值加一。

4. 在字典sum_dict中找到值最大的initial节点返回。

代码如下:

python 复制代码
from collections import deque


class Solution(object):
    def minMalwareSpread(self, graph, initial):
        """
        :type graph: List[List[int]]
        :type initial: List[int]
        :rtype: int
        """
        # 将互相能到达的节点们视为一个组,(如果initial中有属于这一组的节点)每组的节点数量即为这一个小网络的感染恶意软件的最终节点数
        n = len(graph)
        sum_dict = {}  # 字典sum_dict记录initial节点能且只能凭自己感染的节点数
        visited = [-1] * n  # 数组visited记录节点能被多少initial节点凭自己感染("≥0"表示唯一的initial节点索引;"-2"表示有多个initial节点连接)

        def connectedNodes(graph, initial, node):
            judged = [-1] * n    # 表示在这次遍历中,节点是否已经判断过了
            queue = deque()  # 队列储存待判断相邻节点的节点
            queue.append(node)
            while queue:
                x = queue.popleft()
                for k in range(n):
                    if k == x:  # 跳过当前节点本身
                        continue
                    if judged[k] == -1 and graph[x][k] == 1 and k not in queue and k not in initial:
                        queue.append(k)
                        judged[k] = 1
                        if visited[k] == -1:
                            visited[k] = node
                        elif visited[k] >= 0 and visited[k] != node and graph[x][k] == 1:
                            visited[k] = -2

        for i in initial:
            connectedNodes(graph, initial, i)
            sum_dict[i] = 1

        for j in range(n):
            if visited[j] >= 0:
                sum_dict[visited[j]] += 1

        m = 0
        for key, value in sum_dict.items():    # 在字典sum_dict中找到值最大的initial节点返回
            if value > m:
                m = value
                res = key
            if value == m and key < res:
                res = key
        return res

提交通过,debug了一万年,泪目:

相关推荐
Csvn1 小时前
Python 两大经典坑点 —— 可变默认参数 & 闭包延迟绑定
后端·python
曲幽2 小时前
别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了
python·docker·web·pot·translate·libretranslate·arogstranslate
猿人谷3 小时前
不只是 CPU 阈值:STAR 如何用 GAT + Transformer 做容器级自动扩缩容?
人工智能·算法
用户556918817534 小时前
#从脚本到独立程序:Python + Playwright 批量抓取的完整踩坑记录
python·自动化运维
复杂网络4 小时前
Stable Diffusion 视觉大模型微调技术深度调研
算法
复杂网络4 小时前
基于 Stable Diffusion 架构的视觉大模型代表性工作与原理深度解析
算法
MrZhao4004 小时前
Agent Loop 如何用 Hook 扩展:权限、日志与工具拦截
算法
MrZhao4004 小时前
Agent 为什么需要 Skills:别把所有知识都塞进 system prompt
算法
兵慌码乱18 小时前
基于 MediaPipe 与 PySide2 的手势交互音乐控制系统实现:轻量化视觉交互全流程解析
python·opencv·计算机视觉·人机交互·手势识别·mediapipe·pyside2
luckdewei20 小时前
FastAPI 资产管理系统实战:复杂 ORM 关联、Alembic 迁移与 N+1 查询优化
python