Day4 减少恶意传播的软件

1.题目描述

链接:924. 尽量减少恶意软件的传播 – 力扣(LeetCode)

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

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

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

如果从 initial 中移除某一节点能够最小化 M(initial), 返回该节点。如果有多个节点满足条件,就返回索引最小的节点。

请注意,如果某个节点已从受感染节点的列表 initial 中删除,它以后仍有可能因恶意软件传播而受到感染。

示例

输入:graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1]

输出:0

输入:graph = [[1,0,0],[0,1,0],[0,0,1]], initial = [0,2]

输出:0

2.题目分析

思路1

一道hard题,需要注意几个细节:1.移除这个节点只是把“感染属性”给移除了,也就是它不能够主动感染,但是还是可能被间接感染的。2.感染可能会出现多次间接感染,查找需要查找完。

思路:1.对于每一个initial当中感染的节点,查找它构成的连通图,这里采用BFS的方式,如果其他initial的节点也在这个连通图当中,那么这几个在同一个连通图的initial节点删除也没有用,因为还会被感染,所以不用考虑;2.因为连通数量可能是多次间接的,因此用一个count去记录每一个initial感染节点所能感染的节点数;3.都会被感染的时候返回最小的index

思路2

采用官方题解的思路,1.一开始找到所有的连通分量,并记录每个节点所在的连通分量;2.记录每个连通分量的大小;3.遍历initial,记录每一个感染节点对应的连通分量,如果多个节点对应同一个连通分量,则删除也没有用,因此我们需要找到对应感染节点数只为1的连通分量

3.代码实现

思路1代码实现

class Solution {
private:
	unordered_set<int>initSet;
	bool findArrive(vector<vector<int>>& graph, vector<int>& initial, vector<bool>& arrive,int index, vector<int>&count)
	{
		bool add = false;  //判断节点是否会被相互感染
		stack<int>q;
		q.push(initial[index]);
		while (!q.empty())
		{
			int i = q.top();
			q.pop();
			for (int j = 0; j < graph.size(); ++j)
			{
				if (graph[i][j] && !arrive[j])
				{
					q.push(j);
					arrive[j] = true;
					count[index]++;
					if(initSet.count(j) && j != initial[index])
						add = true;
				}
					
			}
		}
		return add;
	}
public:
	int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
		const int N = initial.size();
		int minIndex = graph.size();
		//sort(initial.begin(), initial.end());
		initSet = std::move(unordered_set<int>(initial.begin(), initial.end()));
		vector<bool>arrive(graph.size(), false);
		vector<int>count(N);
		for (int i = 0; i < N; ++i)
		{
			//对于任意一个节点查找它所能感染的其他所有节点,然后看是不是在initial里面
			//这里对于没有感染也会报错
			if (!arrive[initial[i]])
			{
				arrive[initial[i]] = true;
				if(!findArrive(graph, initial, arrive,i,count))
					arrive[initial[i]] = false;
			}
			minIndex = min(minIndex, initial[i]);
		}

		//记录不会被相互感染的initial节点
		vector<int>single;
		for (int i = 0; i < N; ++i)
		{
			if (!arrive[initial[i]])
				single.push_back(i);
		}		
		if (single.empty())
			return minIndex;

		minIndex = initial[single[0]];
		int maxValue = 0;
		for (int i = 0; i < single.size(); ++i)
		{
			if (count[single[i]] > maxValue)
			{
				minIndex = initial[single[i]];
				maxValue = count[single[i]];
			}
			else if (count[single[i]] == maxValue)
				minIndex = min(minIndex, initial[single[i]]);
		}
		return minIndex;
	}
};

思路2代码实现

class Solution {
public:
	int minMalwareSpread(vector<vector<int>>& graph, vector<int>& initial) {
		//官方思路重写
		const int N = graph.size();
		queue<int>q;
		vector<int>idIn(N);
		unordered_map<int, int>id_to_size;  //记录连通分量大小
		int id = 0;
		for (int i = 0; i < N; ++i)
		{
			if (!idIn[i])  //这个节点没有连通分量
			{
				++id;
				idIn[i] = id;
				int size = 1;
				q.push(i);
				while (!q.empty())
				{
					int index = q.front();
					q.pop();
					for (int j = 0; j < N; ++j)
					{
						if (!idIn[j] && graph[index][j])
						{
							idIn[j] = id;
							++size;
							q.push(j);
						}
					}
				}
				id_to_size[id] = size;
			}
		}

		unordered_map<int, int>node_to_id;
		for (int node : initial)
		{
			node_to_id[idIn[node]]++;
		}
		int minIndex = N + 1;
		int maxValue = 0;
		for (int node : initial)
		{
			int remove = node_to_id[idIn[node]] == 1 ? id_to_size[idIn[node]] : 0;
			if (maxValue < remove || (maxValue == remove && node < minIndex))
			{
				maxValue = remove;
				minIndex = node;
			}
		}
		return minIndex;
	}
};
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇