Solving Leetcode Interviews in Seconds with AI: Minimize Malware Spread II
Introduction
In this blog post, we will explore how to solve the LeetCode problem "928" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
You are given a network of n nodes represented as an n x n adjacency matrix graph, where the ith node is directly connected to the jth node if graph[i][j] == 1. Some nodes initial are initially infected by malware. Whenever two nodes are directly connected, and at least one of those two nodes is infected by malware, both nodes will be infected by malware. This spread of malware will continue until no more nodes can be infected in this manner. Suppose M(initial) is the final number of nodes infected with malware in the entire network after the spread of malware stops. We will remove exactly one node from initial, completely removing it and any connections from this node to any other node. Return the node that, if removed, would minimize M(initial). If multiple nodes could be removed to minimize M(initial), return such a node with the smallest index. Example 1: Input: graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1] Output: 0 Example 2: Input: graph = [[1,1,0],[1,1,1],[0,1,1]], initial = [0,1] Output: 1 Example 3: Input: graph = [[1,1,0,0],[1,1,1,0],[0,1,1,1],[0,0,1,1]], initial = [0,1] Output: 1 Constraints: n == graph.length n == graph[i].length 2 <= n <= 300 graph[i][j] is 0 or 1. graph[i][j] == graph[j][i] graph[i][i] == 1 1 <= initial.length < n 0 <= initial[i] <= n - 1 All the integers in initial are unique.
Explanation
Here's the breakdown of the solution:
- Identify Connected Components: Use Depth-First Search (DFS) or Breadth-First Search (BFS) to find connected components in the graph. The initial malware nodes might belong to different connected components.
- Analyze Impact of Removing Each Initial Node: For each node in the
initiallist, temporarily remove it from theinitiallist and determine how many nodes will be infected after the malware spread. Compare the resulting infected node counts to find the node that minimizes the final infected count. Handle Ties: If multiple nodes minimize the infected count, choose the node with the smallest index.
Runtime Complexity: O(n * (n + m)), where n is the number of nodes and m is the number of edges in the graph. This is because for each initial node, we potentially perform a DFS/BFS on the graph. Storage Complexity: O(n) due to the visited array used in DFS/BFS.
Code
def minMalwareSpread(graph, initial):
"""
Finds the node to remove from the initial set to minimize the final malware spread.
Args:
graph: An adjacency matrix representing the network.
initial: A list of initially infected nodes.
Returns:
The node to remove that minimizes the malware spread.
"""
n = len(graph)
initial = sorted(initial) # Sort initial for tie-breaking
def dfs(node, infected, visited, current_component):
visited[node] = True
current_component.add(node)
for neighbor in range(n):
if graph[node][neighbor] == 1 and not visited[neighbor] and neighbor not in infected:
dfs(neighbor, infected, visited, current_component)
def get_infected_count(infected_nodes):
visited = [False] * n
infected_count = 0
for node in range(n):
if node in infected_nodes and not visited[node]:
dfs(node, infected_nodes, visited, set()) # Start DFS from infected node
infected_count = sum(visited)
return infected_count
best_node = -1
min_infected = float('inf')
for node_to_remove in initial:
temp_initial = set(initial)
temp_initial.remove(node_to_remove)
infected_count = get_infected_count(temp_initial)
if infected_count < min_infected:
min_infected = infected_count
best_node = node_to_remove
elif infected_count == min_infected and node_to_remove < best_node:
best_node = node_to_remove
return best_node if best_node != -1 else min(initial) # Handle empty initial case