Skip to content

Add solution and test-cases for problem 1948 #1265

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

Merged
merged 1 commit into from
Aug 3, 2025
Merged
Show file tree
Hide file tree
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,63 @@
# [1948.Delete Duplicate Folders in System][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
Due to a bug, there are many duplicate folders in a file system. You are given a 2D array `paths`, where `paths[i]` is an array representing an absolute path to the `ith` folder in the file system.

- For example, `["one", "two", "three"]` represents the path `"/one/two/three"`.

Two folders (not necessarily on the same level) are **identical** if they contain the **same non-empty** set of identical subfolders and underlying subfolder structure. The folders **do not** need to be at the root level to be identical. If two or more folders are **identical**, then **mark** the folders as well as all their subfolders.

- For example, folders `"/a"` and `"/b"` in the file structure below are identical. They (as well as their subfolders) should **all** be marked:

- `/a`
- `/a/x`
- `/a/x/y`
- `/a/z`
- `/b`
- `/b/x`
- `/b/x/y`
- `/b/z`

- However, if the file structure also included the path `"/b/w"`, then the folders `"/a"` and `"/b"` would not be identical. Note that `"/a/x"` and `"/b/x"` would still be considered identical even with the added folder.

Once all the identical folders and their subfolders have been marked, the file system will **delete** all of them. The file system only runs the deletion once, so any folders that become identical after the initial deletion are not deleted.

**Example 1:**
Return the 2D array `ans` containing the paths of the **remaining** folders after deleting all the marked folders. The paths may be returned in **any** order.

**Example 1:**

![1](./1.jpg)

```
Input: a = "11", b = "1"
Output: "100"
Input: paths = [["a"],["c"],["d"],["a","b"],["c","b"],["d","a"]]
Output: [["d"],["d","a"]]
Explanation: The file structure is as shown.
Folders "/a" and "/c" (and their subfolders) are marked for deletion because they both contain an empty
folder named "b".
```

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

## 题解
![2](./2.jpg)

### 思路1
> ...
Delete Duplicate Folders in System
```go
```
Input: paths = [["a"],["c"],["a","b"],["c","b"],["a","b","x"],["a","b","x","y"],["w"],["w","y"]]
Output: [["c"],["c","b"],["a"],["a","b"]]
Explanation: The file structure is as shown.
Folders "/a/b/x" and "/w" (and their subfolders) are marked for deletion because they both contain an empty folder named "y".
Note that folders "/a" and "/c" are identical after the deletion, but they are not deleted because they were not marked beforehand.
```

**Example 3:**

![3](./3.jpg)

```
Input: paths = [["a","b"],["c","d"],["c"],["a"]]
Output: [["c"],["c","d"],["a"],["a","b"]]
Explanation: All folders are unique in the file system.
Note that the returned array can be in a different order as the order does not matter.
```

## 结语

Expand Down
107 changes: 105 additions & 2 deletions leetcode/1901-2000/1948.Delete-Duplicate-Folders-in-System/Solution.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,108 @@
package Solution

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

type Tree struct {
Value string
ValueIndex map[string]int
Children []*Tree
Del bool
}

func Solution(paths [][]string) [][]string {
sort.Slice(paths, func(i, j int) bool {
a, b := len(paths[i]), len(paths[j])
l := min(a, b)
for k := range l {
if paths[i][k] != paths[j][k] {
return paths[i][k] < paths[j][k]
}
}
return a < b
})
// 将所有的子目录序列化成一个字符串。之前有过这样的题,搞成字符串
root := &Tree{Value: "/", Children: []*Tree{}, ValueIndex: map[string]int{}}
var buildTree func([]string)
buildTree = func(p []string) {
walker := root
for _, sub := range p {
index, ok := walker.ValueIndex[sub]
if ok {
walker = walker.Children[index]
continue
}
tree := &Tree{
Value: sub, Children: []*Tree{}, ValueIndex: map[string]int{},
}
walker.Children = append(walker.Children, tree)
walker.ValueIndex[sub] = len(walker.Children) - 1
walker = tree
}
}
for _, path := range paths {
buildTree(path)
}

var buildNodeFlag func(*Tree) string

pathToNode := map[string][]*Tree{}
buildNodeFlag = func(node *Tree) string {
if node == nil {
return "#"
}
if len(node.Children) == 0 {
return node.Value + "#"
}
sb := strings.Builder{}
for i, c := range node.Children {
tmp := buildNodeFlag(c) + fmt.Sprintf("%d", i)
sb.WriteString(tmp)
}
s := sb.String()
pathToNode[s] = append(pathToNode[s], node)
return node.Value + s
}
buildNodeFlag(root)
for path, nodes := range pathToNode {
if len(path) == 0 {
continue
}
if len(nodes) > 1 {
// 有重复的
for _, n := range nodes {
n.Del = true
}
}
}
var filterPath func([]string) []string
filterPath = func(cur []string) []string {
walker := root
i := 0
for ; i < len(cur); i++ {
index := walker.ValueIndex[cur[i]]
if walker.Children[index].Del {
break
}
walker = walker.Children[index]
}
return cur[:i]
}
in := map[string]struct{}{}
var ans [][]string
for _, path := range paths {
res := filterPath(path)
if len(res) > 0 {
key := strings.Join(res, "/")
if _, ok := in[key]; ok {
continue
}
ans = append(ans, res)
in[key] = struct{}{}
}
}
return ans
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,25 @@ func TestSolution(t *testing.T) {
// 测试用例
cases := []struct {
name string
inputs bool
expect bool
inputs [][]string
expect [][]string
}{
{"TestCase", true, true},
{"TestCase", true, true},
{"TestCase", false, false},
{"TestCase1", [][]string{
{"a"}, {"c"}, {"d"}, {"a", "b"},
{"c", "b"}, {"d", "a"},
}, [][]string{{"d"}, {"d", "a"}}},
{"TestCase2", [][]string{
{"a"}, {"c"}, {"a", "b"}, {"c", "b"}, {"a", "b", "x"},
{"a", "b", "x", "y"}, {"w"}, {"w", "y"},
}, [][]string{
{"a"}, {"a", "b"},
{"c"}, {"c", "b"},
}},
{"TestCase3", [][]string{
{"a", "b"}, {"c", "d"}, {"c"}, {"a"},
}, [][]string{
{"a"}, {"a", "b"}, {"c"}, {"c", "d"},
}},
}

// 开始测试
Expand All @@ -30,10 +43,10 @@ func TestSolution(t *testing.T) {
}
}

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

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