Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added solution 1203-Sort Items by Groups Respecting Dependencies #3730

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions python/1203-sort-items-by-groups-respecting-dependencies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from collections import defaultdict, deque
from typing import List
class Solution:
# This function performs topological sort on a directed graph represented by successors and predecessors_count arrays.
def topologicalSort(self, successors: List[List[int]], predecessors_count: List[int], num_nodes: int) -> List[int]:
order = [] # To store the topologically sorted nodes
# Initialize a deque with all nodes that have no predecessors (i.e., in-degree of 0)
nodes_with_no_predecessors = deque(node for node in range(num_nodes) if not predecessors_count[node])

while nodes_with_no_predecessors: # Process nodes while there are nodes without predecessors
node = nodes_with_no_predecessors.popleft() # Get the node with no predecessors
order.append(node) # Add the node to the sorted order
for successor in successors[node]: # For each successor of the current node
predecessors_count[successor] -= 1 # Decrement the in-degree of the successor
if not predecessors_count[successor]: # If the successor now has no predecessors
nodes_with_no_predecessors.append(successor) # Add it to the queue for processing

# If the number of nodes in the order is less than the total number of nodes, a cycle was detected
return order if len(order) == num_nodes else [] # Return the order if all nodes were sorted, else return empty list

def sortItems(self, n: int, m: int, group: List[int], beforeItems: List[List[int]]) -> List[int]:
# Step 1: Assign unique group IDs to items that don't belong to any group
for item in range(n):
if group[item] == -1: # If the item doesn't belong to any group
group[item] = m # Assign a new group ID
m += 1 # Increment the group ID for the next item

# Step 2: Initialize graphs for item dependencies and group dependencies
successors_group, successors_item = [[] for _ in range(m)], [[] for _ in range(n)] # Graphs for group and item dependencies
predecessors_count_group, predecessors_count_item = [0] * m, [0] * n # Count of incoming edges (predecessors) for each group and item

# Step 3: Build the dependency graphs based on beforeItems
for item in range(n):
current_group = group[item] # Get the group of the current item
for before in beforeItems[item]: # Process each item that should come before the current item
before_group = group[before] # Get the group of the item that should come before

if current_group == before_group: # If the two items belong to the same group
successors_item[before].append(item) # Add a dependency from 'before' to the current item
predecessors_count_item[item] += 1 # Increment the in-degree of the current item
else: # If the items belong to different groups
successors_group[before_group].append(current_group) # Add a group dependency
predecessors_count_group[current_group] += 1 # Increment the in-degree of the current group

# Step 4: Perform topological sort on both the group dependencies and item dependencies
groups_order = self.topologicalSort(successors_group, predecessors_count_group, m) # Topological sort of groups
items_order = self.topologicalSort(successors_item, predecessors_count_item, n) # Topological sort of items

# Step 5: If there was a cycle detected in either group or item sorting, return an empty list
if not groups_order or not items_order:
return [] # Return an empty list if either the group or item topological sort failed

# Step 6: Group the items based on the group IDs
items_grouped = [[] for _ in range(m)] # Create an empty list for each group to store its items
for item in items_order: # Process each item in topologically sorted order
items_grouped[group[item]].append(item) # Add the item to the appropriate group

# Step 7: Combine the groups in topologically sorted order
result = [] # The final result list to store the sorted items
for grp in groups_order: # For each group in topologically sorted order
result.extend(items_grouped[grp]) # Add the items of the group to the result

return result # Return the final sorted list of items respecting both item and group dependencies