Skip to content

Commit

Permalink
Merge pull request #600 from 0xff-dev/1203
Browse files Browse the repository at this point in the history
Add solution and test-cases for problem 1203
  • Loading branch information
6boris authored Aug 22, 2023
2 parents 84e00c3 + e2d5c5f commit cb950b4
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 28 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
# [1203.Sort Items by Groups Respecting Dependencies][title]

> [!WARNING|style:flat]
> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm)
## Description
There are `n` items each belonging to zero or one of `m` groups where `group[i]` is the group that the `i`-th item belongs to and it's equal to `-1` if the `i`-th item belongs to no group. The items and the groups are zero indexed. A group can have no item belonging to it.

**Example 1:**
Return a sorted list of the items such that:

```
Input: a = "11", b = "1"
Output: "100"
```
- The items that belong to the same group are next to each other in the sorted list.
- There are some relations between these items where `beforeItems[i]` is a list containing all the items that should come before the `i`-th item in the sorted array (to the left of the `i`-th item).

Return any solution if there is more than one solution and return an **empty list** if there is no solution.

## 题意
> ...
**Example 1:**

## 题解
![example1](./1359_ex1.png)

### 思路1
> ...
Sort Items by Groups Respecting Dependencies
```go
```
Input: n = 8, m = 2, group = [-1,-1,1,0,0,1,0,-1], beforeItems = [[],[6],[5],[6],[3,6],[],[],[]]
Output: [6,3,4,1,5,2,0,7]
```

**Example 2:**

```
Input: n = 8, m = 2, group = [-1,-1,1,0,0,1,0,-1], beforeItems = [[],[6],[5],[6],[3],[],[4],[]]
Output: []
Explanation: This is the same as example 1 except that 4 needs to be before 6 in the sorted list.
```

## 结语

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,163 @@
package Solution

func Solution(x bool) bool {
return x
import "sort"

func Solution(n int, m int, group []int, beforeItems [][]int) []int {
groupItems := make(map[int][]int)
item2Group := make(map[int]int)
for idx, g := range group {
if g == -1 {
g = m + idx
}
item2Group[idx] = g
if _, ok := groupItems[g]; !ok {
groupItems[g] = make([]int, 0)
}
groupItems[g] = append(groupItems[g], idx)
}

/*
for g, items := range groupItems {
fmt.Printf("group: %d -- %v\n", g, items)
}
for item, g := range item2Group {
fmt.Printf("itme: %d -- %d\n", item, g)
}
*/
groupItemOrder := make(map[int]map[int][]int)
groupItemIn := make(map[int]map[int]int)

groupOrder := make(map[int][]int)
groupIn := make(map[int]int)
for idx, before := range beforeItems {
idxGroup := item2Group[idx]

for _, item := range before {
itemGroup := item2Group[item]
if itemGroup == idxGroup {
if _, ok := groupItemOrder[idxGroup]; !ok {
groupItemOrder[idxGroup] = make(map[int][]int)
}
if _, ok := groupItemOrder[idxGroup][item]; !ok {
groupItemOrder[idxGroup][item] = make([]int, 0)
}
groupItemOrder[idxGroup][item] = append(groupItemOrder[idxGroup][item], idx)

if _, ok := groupItemIn[idxGroup]; !ok {
groupItemIn[idxGroup] = make(map[int]int)
}
groupItemIn[idxGroup][idx]++
continue
}
if _, ok := groupOrder[itemGroup]; !ok {
groupOrder[itemGroup] = make([]int, 0)
}
groupOrder[itemGroup] = append(groupOrder[itemGroup], idxGroup)
groupIn[idxGroup]++
}
}

/*
fmt.Printf("groupItemOrder; %+v\n", groupItemOrder)
fmt.Printf("groupOrder: %+v\n", groupOrder)
fmt.Printf("groupIn: %+v\n", groupIn)
*/
var groupTopology func(int) bool
groupTopology = func(groupID int) bool {
items := groupItems[groupID]
if len(items) == 1 {
return true
}
newOrder := make([]int, 0)
relation := groupItemOrder[groupID]
in := groupItemIn[groupID]

queue := make([]int, 0)
used := 0
for _, item := range items {
if _, ok := in[item]; !ok {
queue = append(queue, item)
newOrder = append(newOrder, item)
used++
}
}
if len(queue) == 0 {
return false
}
// The sorting is added here for test cases, and can be removed from the actual commit code
sort.Ints(newOrder)
for len(queue) > 0 {
n := make([]int, 0)
for _, i := range queue {
for _, rel := range relation[i] {
in[rel]--
if in[rel] == 0 {
n = append(n, rel)
}
}
}
if len(n) == 0 && used != len(items) {
return false
}
queue = n
used += len(n)
// The sorting is added here for test cases, and can be removed from the actual commit code
sort.Ints(n)
newOrder = append(newOrder, n...)
}

groupItems[groupID] = newOrder
return true
}
// 先检查每个组是否可以满足要求
for groupID := range groupItems {
if !groupTopology(groupID) {
//fmt.Printf("group; %d, don't", groupID)
return nil
}
}

queue := make([]int, 0)
newGroupOrder := make([]int, 0)
used := 0
for i := range groupItems {
if _, ok := groupIn[i]; !ok {
queue = append(queue, i)
//fmt.Printf("add group: %d\n", i)
newGroupOrder = append(newGroupOrder, i)
used++
}
}
if used == 0 {
return nil
}
// The sorting is added here for test cases, and can be removed from the actual commit code
sort.Ints(newGroupOrder)

for len(queue) > 0 {
n := make([]int, 0)
for _, item := range queue {
for _, rel := range groupOrder[item] {
groupIn[rel]--
if groupIn[rel] == 0 {
n = append(n, rel)
}
}
}
if len(n) == 0 && used != len(groupItems) {
return nil
}
queue = n
// The sorting is added here for test cases, and can be removed from the actual commit code
sort.Ints(n)
newGroupOrder = append(newGroupOrder, n...)
used += len(n)
}

ans := make([]int, 0)
for _, g := range newGroupOrder {
ans = append(ans, groupItems[g]...)
}

return ans
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,36 @@ import (
func TestSolution(t *testing.T) {
// 测试用例
cases := []struct {
name string
inputs bool
expect bool
name string
n, m int
group []int
beforeItems [][]int
expect []int
}{
{"TestCase", true, true},
{"TestCase", true, true},
{"TestCase", false, false},
{"TestCase1", 8, 2, []int{-1, -1, 1, 0, 0, 1, 0, -1}, [][]int{
{}, {6}, {5}, {6}, {3, 6}, {}, {}, {},
}, []int{6, 3, 4, 5, 2, 0, 7, 1}},
{"TestCase2", 8, 2, []int{-1, -1, 1, 0, 0, 1, 0, -1}, [][]int{
{}, {6}, {5}, {6}, {3}, {}, {4}, {},
}, nil},
}

// 开始测试
for i, c := range cases {
t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) {
got := Solution(c.inputs)
got := Solution(c.n, c.m, c.group, c.beforeItems)
if !reflect.DeepEqual(got, c.expect) {
t.Fatalf("expected: %v, but got: %v, with inputs: %v",
c.expect, got, c.inputs)
t.Fatalf("expected: %v, but got: %v, with inputs: %v %v %v %v",
c.expect, got, c.n, c.m, c.group, c.beforeItems)
}
})
}
}

// 压力测试
// 压力测试
func BenchmarkSolution(b *testing.B) {
}

// 使用案列
// 使用案列
func ExampleSolution() {
}

0 comments on commit cb950b4

Please sign in to comment.