Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 461e6ad

Browse files
committed
feat: add solutions to lc problem: No.1203
No.1203.Sort Items by Groups Respecting Dependencies
1 parent dbcdaea commit 461e6ad

File tree

7 files changed

+981
-0
lines changed

7 files changed

+981
-0
lines changed

‎solution/1200-1299/1203.Sort Items by Groups Respecting Dependencies/README.md‎

Lines changed: 338 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,360 @@
5454

5555
<!-- 这里可写通用的实现逻辑 -->
5656

57+
**方法一:拓扑排序**
58+
59+
我们先遍历数组 $group,ドル对于每个项目,如果其不属于任何小组,则将其新建一个小组,编号为 $m,ドル并将 $m$ 的值加一。这样我们就能保证所有项目都属于某个小组了。然后,我们用一个数组 $groupItems$ 记录每个小组包含的项目,数组下标为小组编号,数组值为包含的项目列表。
60+
61+
接下来,我们需要建图。对于每个项目,我们需要建立两种图,一种是项目间的图,一种是小组间的图。我们遍历数组 $group,ドル对于当前项目 $i,ドル它所在的小组为 $group[i],ドル我们遍历 $beforeItems[i],ドル对于其中的每个项目 $j,ドル如果 $group[i] = group[j],ドル说明 $i$ 和 $j$ 属于同一小组,我们在项目图中添加一条 $j \to i$ 的边,否则说明 $i$ 和 $j$ 属于不同的小组,我们在小组间的图中添加一条 $group[j] \to group[i]$ 的边,并且更新对应的入度数组。
62+
63+
接下来,我们先对小组间的图进行拓扑排序,得到排序后的小组列表 $groupOrder,ドル如果排序后的列表长度不等于小组总数,说明无法完成排序,返回空列表。否则,我们遍历 $groupOrder,ドル对于其中的每个小组 $gi,ドル我们将该小组包含的项目列表 $groupItems[gi]$ 进行拓扑排序,得到排序后的项目列表 $itemOrder,ドル如果排序后的列表长度不等于该小组包含的项目总数,说明无法完成排序,返回空列表。否则,我们将 $itemOrder$ 中的项目加入答案数组中,最终返回该答案数组即可。
64+
65+
时间复杂度 $O(n + m),ドル空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别是项目总数和小组总数。
66+
5767
<!-- tabs:start -->
5868

5969
### **Python3**
6070

6171
<!-- 这里可写当前语言的特殊实现逻辑 -->
6272

6373
```python
74+
class Solution:
75+
def sortItems(
76+
self, n: int, m: int, group: List[int], beforeItems: List[List[int]]
77+
) -> List[int]:
78+
def topo_sort(degree, graph, items):
79+
q = deque(i for _, i in enumerate(items) if degree[i] == 0)
80+
res = []
81+
while q:
82+
i = q.popleft()
83+
res.append(i)
84+
for j in graph[i]:
85+
degree[j] -= 1
86+
if degree[j] == 0:
87+
q.append(j)
88+
return res if len(res) == len(items) else []
89+
90+
idx = m
91+
group_items = [[] for _ in range(n + m)]
92+
for i, g in enumerate(group):
93+
if g == -1:
94+
group[i] = idx
95+
idx += 1
96+
group_items[group[i]].append(i)
6497

98+
item_degree = [0] * n
99+
group_degree = [0] * (n + m)
100+
item_graph = [[] for _ in range(n)]
101+
group_graph = [[] for _ in range(n + m)]
102+
for i, gi in enumerate(group):
103+
for j in beforeItems[i]:
104+
gj = group[j]
105+
if gi == gj:
106+
item_degree[i] += 1
107+
item_graph[j].append(i)
108+
else:
109+
group_degree[gi] += 1
110+
group_graph[gj].append(gi)
111+
112+
group_order = topo_sort(group_degree, group_graph, range(n + m))
113+
if not group_order:
114+
return []
115+
ans = []
116+
for gi in group_order:
117+
items = group_items[gi]
118+
item_order = topo_sort(item_degree, item_graph, items)
119+
if len(items) != len(item_order):
120+
return []
121+
ans.extend(item_order)
122+
return ans
65123
```
66124

67125
### **Java**
68126

69127
<!-- 这里可写当前语言的特殊实现逻辑 -->
70128

71129
```java
130+
class Solution {
131+
public int[] sortItems(int n, int m, int[] group, List<List<Integer>> beforeItems) {
132+
int idx = m;
133+
List<Integer>[] groupItems = new List[n + m];
134+
int[] itemDegree = new int[n];
135+
int[] groupDegree = new int[n + m];
136+
List<Integer>[] itemGraph = new List[n];
137+
List<Integer>[] groupGraph = new List[n + m];
138+
Arrays.setAll(groupItems, k -> new ArrayList<>());
139+
Arrays.setAll(itemGraph, k -> new ArrayList<>());
140+
Arrays.setAll(groupGraph, k -> new ArrayList<>());
141+
for (int i = 0; i < n; ++i) {
142+
if (group[i] == -1) {
143+
group[i] = idx++;
144+
}
145+
groupItems[group[i]].add(i);
146+
}
147+
for (int i = 0; i < n; ++i) {
148+
for (int j : beforeItems.get(i)) {
149+
if (group[i] == group[j]) {
150+
++itemDegree[i];
151+
itemGraph[j].add(i);
152+
} else {
153+
++groupDegree[group[i]];
154+
groupGraph[group[j]].add(group[i]);
155+
}
156+
}
157+
}
158+
List<Integer> items = new ArrayList<>();
159+
for (int i = 0; i < n + m; ++i) {
160+
items.add(i);
161+
}
162+
var groupOrder = topoSort(groupDegree, groupGraph, items);
163+
if (groupOrder.isEmpty()) {
164+
return new int[0];
165+
}
166+
List<Integer> ans = new ArrayList<>();
167+
for (int gi : groupOrder) {
168+
items = groupItems[gi];
169+
var itemOrder = topoSort(itemDegree, itemGraph, items);
170+
if (itemOrder.size() != items.size()) {
171+
return new int[0];
172+
}
173+
ans.addAll(itemOrder);
174+
}
175+
return ans.stream().mapToInt(Integer::intValue).toArray();
176+
}
177+
178+
private List<Integer> topoSort(int[] degree, List<Integer>[] graph, List<Integer> items) {
179+
Deque<Integer> q = new ArrayDeque<>();
180+
for (int i : items) {
181+
if (degree[i] == 0) {
182+
q.offer(i);
183+
}
184+
}
185+
List<Integer> ans = new ArrayList<>();
186+
while (!q.isEmpty()) {
187+
int i = q.poll();
188+
ans.add(i);
189+
for (int j : graph[i]) {
190+
if (--degree[j] == 0) {
191+
q.offer(j);
192+
}
193+
}
194+
}
195+
return ans.size() == items.size() ? ans : List.of();
196+
}
197+
}
198+
```
199+
200+
### **C++**
201+
202+
```cpp
203+
class Solution {
204+
public:
205+
vector<int> sortItems(int n, int m, vector<int>& group, vector<vector<int>>& beforeItems) {
206+
int idx = m;
207+
vector<vector<int>> groupItems(n + m);
208+
vector<int> itemDegree(n);
209+
vector<int> groupDegree(n + m);
210+
vector<vector<int>> itemGraph(n);
211+
vector<vector<int>> groupGraph(n + m);
212+
for (int i = 0; i < n; ++i) {
213+
if (group[i] == -1) {
214+
group[i] = idx++;
215+
}
216+
groupItems[group[i]].push_back(i);
217+
}
218+
for (int i = 0; i < n; ++i) {
219+
for (int j : beforeItems[i]) {
220+
if (group[i] == group[j]) {
221+
++itemDegree[i];
222+
itemGraph[j].push_back(i);
223+
} else {
224+
++groupDegree[group[i]];
225+
groupGraph[group[j]].push_back(group[i]);
226+
}
227+
}
228+
}
229+
vector<int> items(n + m);
230+
iota(items.begin(), items.end(), 0);
231+
auto topoSort = [](vector<vector<int>>& graph, vector<int>& degree, vector<int>& items) -> vector<int> {
232+
queue<int> q;
233+
for (int& i : items) {
234+
if (degree[i] == 0) {
235+
q.push(i);
236+
}
237+
}
238+
vector<int> ans;
239+
while (!q.empty()) {
240+
int i = q.front();
241+
q.pop();
242+
ans.push_back(i);
243+
for (int& j : graph[i]) {
244+
if (--degree[j] == 0) {
245+
q.push(j);
246+
}
247+
}
248+
}
249+
return ans.size() == items.size() ? ans : vector<int>();
250+
};
251+
auto groupOrder = topoSort(groupGraph, groupDegree, items);
252+
if (groupOrder.empty()) {
253+
return vector<int>();
254+
}
255+
vector<int> ans;
256+
for (int& gi : groupOrder) {
257+
items = groupItems[gi];
258+
auto itemOrder = topoSort(itemGraph, itemDegree, items);
259+
if (items.size() != itemOrder.size()) {
260+
return vector<int>();
261+
}
262+
ans.insert(ans.end(), itemOrder.begin(), itemOrder.end());
263+
}
264+
return ans;
265+
}
266+
};
267+
```
268+
269+
### **Go**
270+
271+
```go
272+
func sortItems(n int, m int, group []int, beforeItems [][]int) []int {
273+
idx := m
274+
groupItems := make([][]int, n+m)
275+
itemDegree := make([]int, n)
276+
groupDegree := make([]int, n+m)
277+
itemGraph := make([][]int, n)
278+
groupGraph := make([][]int, n+m)
279+
for i, g := range group {
280+
if g == -1 {
281+
group[i] = idx
282+
idx++
283+
}
284+
groupItems[group[i]] = append(groupItems[group[i]], i)
285+
}
286+
for i, gi := range group {
287+
for _, j := range beforeItems[i] {
288+
gj := group[j]
289+
if gi == gj {
290+
itemDegree[i]++
291+
itemGraph[j] = append(itemGraph[j], i)
292+
} else {
293+
groupDegree[gi]++
294+
groupGraph[gj] = append(groupGraph[gj], gi)
295+
}
296+
}
297+
}
298+
items := make([]int, n+m)
299+
for i := range items {
300+
items[i] = i
301+
}
302+
topoSort := func(degree []int, graph [][]int, items []int) []int {
303+
q := []int{}
304+
for _, i := range items {
305+
if degree[i] == 0 {
306+
q = append(q, i)
307+
}
308+
}
309+
ans := []int{}
310+
for len(q) > 0 {
311+
i := q[0]
312+
q = q[1:]
313+
ans = append(ans, i)
314+
for _, j := range graph[i] {
315+
degree[j]--
316+
if degree[j] == 0 {
317+
q = append(q, j)
318+
}
319+
}
320+
}
321+
return ans
322+
}
323+
groupOrder := topoSort(groupDegree, groupGraph, items)
324+
if len(groupOrder) != len(items) {
325+
return nil
326+
}
327+
ans := []int{}
328+
for _, gi := range groupOrder {
329+
items = groupItems[gi]
330+
itemOrder := topoSort(itemDegree, itemGraph, items)
331+
if len(items) != len(itemOrder) {
332+
return nil
333+
}
334+
ans = append(ans, itemOrder...)
335+
}
336+
return ans
337+
}
338+
```
339+
340+
### **TypeScript**
72341

342+
```ts
343+
function sortItems(
344+
n: number,
345+
m: number,
346+
group: number[],
347+
beforeItems: number[][],
348+
): number[] {
349+
let idx = m;
350+
const groupItems: number[][] = new Array(n + m).fill(0).map(() => []);
351+
const itemDegree: number[] = new Array(n).fill(0);
352+
const gorupDegree: number[] = new Array(n + m).fill(0);
353+
const itemGraph: number[][] = new Array(n).fill(0).map(() => []);
354+
const groupGraph: number[][] = new Array(n + m).fill(0).map(() => []);
355+
for (let i = 0; i < n; ++i) {
356+
if (group[i] === -1) {
357+
group[i] = idx++;
358+
}
359+
groupItems[group[i]].push(i);
360+
}
361+
for (let i = 0; i < n; ++i) {
362+
for (const j of beforeItems[i]) {
363+
if (group[i] === group[j]) {
364+
++itemDegree[i];
365+
itemGraph[j].push(i);
366+
} else {
367+
++gorupDegree[group[i]];
368+
groupGraph[group[j]].push(group[i]);
369+
}
370+
}
371+
}
372+
let items = new Array(n + m).fill(0).map((_, i) => i);
373+
const topoSort = (
374+
graph: number[][],
375+
degree: number[],
376+
items: number[],
377+
): number[] => {
378+
const q: number[] = [];
379+
for (const i of items) {
380+
if (degree[i] === 0) {
381+
q.push(i);
382+
}
383+
}
384+
const ans: number[] = [];
385+
while (q.length) {
386+
const i = q.pop()!;
387+
ans.push(i);
388+
for (const j of graph[i]) {
389+
if (--degree[j] === 0) {
390+
q.push(j);
391+
}
392+
}
393+
}
394+
return ans.length === items.length ? ans : [];
395+
};
396+
const groupOrder = topoSort(groupGraph, gorupDegree, items);
397+
if (groupOrder.length === 0) {
398+
return [];
399+
}
400+
const ans: number[] = [];
401+
for (const gi of groupOrder) {
402+
items = groupItems[gi];
403+
const itemOrder = topoSort(itemGraph, itemDegree, items);
404+
if (itemOrder.length !== items.length) {
405+
return [];
406+
}
407+
ans.push(...itemOrder);
408+
}
409+
return ans;
410+
}
73411
```
74412

75413
### **...**

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /