There is an undirected graph consisting of n
nodes numbered from 0
to n - 1
. You are given a 0-indexed integer array vals
of length n
where vals[i]
denotes the value of the ith
node.
You are also given a 2D integer array edges
where edges[i] = [ai, bi]
denotes that there exists an undirected edge connecting nodes ai
and bi.
A star graph is a subgraph of the given graph having a center node containing 0
or more neighbors. In other words, it is a subset of edges of the given graph such that there exists a common node for all edges.
The image below shows star graphs with 3
and 4
neighbors respectively, centered at the blue node.
The star sum is the sum of the values of all the nodes present in the star graph.
Given an integer k
, return the maximum star sum of a star graph containing at most k
edges.
Example 1:
Input: vals = [1,2,3,4,10,-10,-20], edges = [[0,1],[1,2],[1,3],[3,4],[3,5],[3,6]], k = 2 Output: 16 Explanation: The above diagram represents the input graph. The star graph with the maximum star sum is denoted by blue. It is centered at 3 and includes its neighbors 1 and 4. It can be shown it is not possible to get a star graph with a sum greater than 16.
Example 2:
Input: vals = [-5], edges = [], k = 0 Output: -5 Explanation: There is only one possible star graph, which is node 0 itself. Hence, we return -5.
Constraints:
n == vals.length
1 <= n <= 105
-104 <= vals[i] <= 104
0 <= edges.length <= min(n * (n - 1) / 2
, 105)
edges[i].length == 2
0 <= ai, bi <= n - 1
ai != bi
0 <= k <= n - 1
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force strategy involves examining every possible 'star' within the graph to find the one with the largest sum. We consider each node as the center of a potential star and then explore all its neighbors to find the arrangement yielding the highest sum.
Here's how the algorithm would work step-by-step:
def max_star_sum_brute_force(values, edges):
maximum_star_sum = float('-inf')
number_of_nodes = len(values)
# Iterate through each node to consider it as the center of the star.
for center_node in range(number_of_nodes):
neighbor_nodes = []
for edge in edges:
if edge[0] == center_node:
neighbor_nodes.append(edge[1])
elif edge[1] == center_node:
neighbor_nodes.append(edge[0])
# Consider all possible combinations of neighbors.
number_of_neighbors = len(neighbor_nodes)
for i in range(1 << number_of_neighbors):
current_star_sum = values[center_node]
neighbors_in_star = []
for j in range(number_of_neighbors):
# Choose only neighbors where the j-th bit is set.
if (i >> j) & 1:
neighbors_in_star.append(neighbor_nodes[j])
for neighbor_node in neighbors_in_star:
current_star_sum += values[neighbor_node]
# Update the global maximum star sum if needed.
maximum_star_sum = max(maximum_star_sum, current_star_sum)
return maximum_star_sum
The core idea is to find the node that, when connected to its 'best' neighbors, results in the highest possible sum. We focus on the nodes with the most positive connections, as negative connections reduce the overall sum. We can use a simple strategy that doesn't require checking every single possible group of connections.
Here's how the algorithm would work step-by-step:
def maximum_star_sum(node_values, edges, max_number_of_nodes):
number_of_nodes = len(node_values)
adjacency_list = [[] for _ in range(number_of_nodes)]
for start_node, end_node in edges:
adjacency_list[start_node].append(end_node)
adjacency_list[end_node].append(start_node)
max_star_sum_so_far = float('-inf')
for current_node in range(number_of_nodes):
# Need to filter nodes based on connection values
neighbor_values = []
for neighbor_node in adjacency_list[current_node]:
neighbor_values.append(node_values[neighbor_node])
neighbor_values.sort(reverse=True)
current_star_sum = node_values[current_node]
number_of_neighbors_to_add = min(max_number_of_nodes, len(neighbor_values))
# Only add neighbors that contribute positively
for i in range(number_of_neighbors_to_add):
if neighbor_values[i] > 0:
current_star_sum += neighbor_values[i]
else:
break
max_star_sum_so_far = max(max_star_sum_so_far, current_star_sum)
return max_star_sum_so_far
Case | How to Handle |
---|---|
Null or empty graph (no nodes or edges) | Return 0, as there are no stars to sum. |
Graph with only one node | Return the value of the single node since a star requires at least one edge. |
Graph with no edges | Return the maximum value node, as each node is a star with sum equal to its own value. |
All node values are negative | If k > 0, return the largest negative value; if k = 0, return the largest negative value. |
Nodes with extremely large positive or negative values (potential integer overflow) | Use a data type that can accommodate large values (e.g., long) to prevent overflow during summation. |
k is zero (only the central node's value is counted) | Iterate through the node values and return the maximum node value. |
Nodes with duplicate values | The algorithm should handle duplicate node values correctly without affecting the maximum star sum calculation. |
k is larger than the number of neighbors of any node | Only sum as many neighbors as the node has when k is larger than the number of neighbors of a node. |