Skip to content

Commit 776fe07

Browse files
committed
Add solution 0609、0692、0890、1048、1442、1738
1 parent 86370c1 commit 776fe07

File tree

56 files changed

+2894
-1136
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2894
-1136
lines changed

README.md

+1,001-990
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package leetcode
2+
3+
import "strings"
4+
5+
func findDuplicate(paths []string) [][]string {
6+
cache := make(map[string][]string)
7+
for _, path := range paths {
8+
parts := strings.Split(path, " ")
9+
dir := parts[0]
10+
for i := 1; i < len(parts); i++ {
11+
bracketPosition := strings.IndexByte(parts[i], '(')
12+
content := parts[i][bracketPosition+1 : len(parts[i])-1]
13+
cache[content] = append(cache[content], dir+"/"+parts[i][:bracketPosition])
14+
}
15+
}
16+
res := make([][]string, 0, len(cache))
17+
for _, group := range cache {
18+
if len(group) >= 2 {
19+
res = append(res, group)
20+
}
21+
}
22+
return res
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package leetcode
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
type question609 struct {
9+
para609
10+
ans609
11+
}
12+
13+
// para 是参数
14+
// one 代表第一个参数
15+
type para609 struct {
16+
paths []string
17+
}
18+
19+
// ans 是答案
20+
// one 代表第一个答案
21+
type ans609 struct {
22+
one [][]string
23+
}
24+
25+
func Test_Problem609(t *testing.T) {
26+
27+
qs := []question609{
28+
29+
{
30+
para609{[]string{"root/a 1.txt(abcd) 2.txt(efgh)", "root/c 3.txt(abcd)", "root/c/d 4.txt(efgh)", "root 4.txt(efgh)"}},
31+
ans609{[][]string{{"root/a/2.txt", "root/c/d/4.txt", "root/4.txt"}, {"root/a/1.txt", "root/c/3.txt"}}},
32+
},
33+
34+
{
35+
para609{[]string{"root/a 1.txt(abcd) 2.txt(efgh)", "root/c 3.txt(abcd)", "root/c/d 4.txt(efgh)"}},
36+
ans609{[][]string{{"root/a/2.txt", "root/c/d/4.txt"}, {"root/a/1.txt", "root/c/3.txt"}}},
37+
},
38+
}
39+
40+
fmt.Printf("------------------------Leetcode Problem 609------------------------\n")
41+
42+
for _, q := range qs {
43+
_, p := q.ans609, q.para609
44+
fmt.Printf("【input】:%v 【output】:%v\n", p, findDuplicate(p.paths))
45+
}
46+
fmt.Printf("\n\n\n")
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# [609. Find Duplicate File in System](https://leetcode.com/problems/find-duplicate-file-in-system/)
2+
3+
4+
## 题目
5+
6+
Given a list `paths` of directory info, including the directory path, and all the files with contents in this directory, return *all the duplicate files in the file system in terms of their paths*. You may return the answer in **any order**.
7+
8+
A group of duplicate files consists of at least two files that have the same content.
9+
10+
A single directory info string in the input list has the following format:
11+
12+
- `"root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)"`
13+
14+
It means there are `n` files `(f1.txt, f2.txt ... fn.txt)` with content `(f1_content, f2_content ... fn_content)` respectively in the directory "`root/d1/d2/.../dm"`. Note that `n >= 1` and `m >= 0`. If `m = 0`, it means the directory is just the root directory.
15+
16+
The output is a list of groups of duplicate file paths. For each group, it contains all the file paths of the files that have the same content. A file path is a string that has the following format:
17+
18+
- `"directory_path/file_name.txt"`
19+
20+
**Example 1:**
21+
22+
```
23+
Input: paths = ["root/a 1.txt(abcd) 2.txt(efgh)","root/c 3.txt(abcd)","root/c/d 4.txt(efgh)","root 4.txt(efgh)"]
24+
Output: [["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]]
25+
26+
```
27+
28+
**Example 2:**
29+
30+
```
31+
Input: paths = ["root/a 1.txt(abcd) 2.txt(efgh)","root/c 3.txt(abcd)","root/c/d 4.txt(efgh)"]
32+
Output: [["root/a/2.txt","root/c/d/4.txt"],["root/a/1.txt","root/c/3.txt"]]
33+
34+
```
35+
36+
**Constraints:**
37+
38+
- `1 <= paths.length <= 2 * 104`
39+
- `1 <= paths[i].length <= 3000`
40+
- `1 <= sum(paths[i].length) <= 5 * 105`
41+
- `paths[i]` consist of English letters, digits, `'/'``'.'``'('``')'`, and `' '`.
42+
- You may assume no files or directories share the same name in the same directory.
43+
- You may assume each given directory info represents a unique directory. A single blank space separates the directory path and file info.
44+
45+
**Follow up:**
46+
47+
- Imagine you are given a real file system, how will you search files? DFS or BFS?
48+
- If the file content is very large (GB level), how will you modify your solution?
49+
- If you can only read the file by 1kb each time, how will you modify your solution?
50+
- What is the time complexity of your modified solution? What is the most time-consuming part and memory-consuming part of it? How to optimize?
51+
- How to make sure the duplicated files you find are not false positive?
52+
53+
## 题目大意
54+
55+
给定一个目录信息列表,包括目录路径,以及该目录中的所有包含内容的文件,您需要找到文件系统中的所有重复文件组的路径。一组重复的文件至少包括二个具有完全相同内容的文件。输入列表中的单个目录信息字符串的格式如下:`"root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)"`。这意味着有 n 个文件(`f1.txt, f2.txt ... fn.txt` 的内容分别是 `f1_content, f2_content ... fn_content`)在目录 `root/d1/d2/.../dm` 下。注意:n>=1 且 m>=0。如果 m=0,则表示该目录是根目录。该输出是重复文件路径组的列表。对于每个组,它包含具有相同内容的文件的所有文件路径。文件路径是具有下列格式的字符串:`"directory_path/file_name.txt"`
56+
57+
## 解题思路
58+
59+
- 这一题算简单题,考察的是字符串基本操作与 map 的使用。首先通过字符串操作获取目录路径、文件名和文件内容。再使用 map 来寻找重复文件,key 是文件内容,value 是存储路径和文件名的列表。遍历每一个文件,并把它加入 map 中。最后遍历 map,如果一个键对应的值列表的长度大于 1,说明找到了重复文件,可以把这个列表加入到最终答案中。
60+
- 这道题有价值的地方在 **Follow up** 中。感兴趣的读者可以仔细想想以下几个问题:
61+
1. 假设您有一个真正的文件系统,您将如何搜索文件?广度搜索还是宽度搜索?
62+
2. 如果文件内容非常大(GB级别),您将如何修改您的解决方案?
63+
3. 如果每次只能读取 1 kb 的文件,您将如何修改解决方案?
64+
4. 修改后的解决方案的时间复杂度是多少?其中最耗时的部分和消耗内存的部分是什么?如何优化?
65+
5. 如何确保您发现的重复文件不是误报?
66+
67+
## 代码
68+
69+
```go
70+
package leetcode
71+
72+
import "strings"
73+
74+
func findDuplicate(paths []string) [][]string {
75+
cache := make(map[string][]string)
76+
for _, path := range paths {
77+
parts := strings.Split(path, " ")
78+
dir := parts[0]
79+
for i := 1; i < len(parts); i++ {
80+
bracketPosition := strings.IndexByte(parts[i], '(')
81+
content := parts[i][bracketPosition+1 : len(parts[i])-1]
82+
cache[content] = append(cache[content], dir+"/"+parts[i][:bracketPosition])
83+
}
84+
}
85+
res := make([][]string, 0, len(cache))
86+
for _, group := range cache {
87+
if len(group) >= 2 {
88+
res = append(res, group)
89+
}
90+
}
91+
return res
92+
}
93+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package leetcode
2+
3+
import "container/heap"
4+
5+
func topKFrequent(words []string, k int) []string {
6+
m := map[string]int{}
7+
for _, word := range words {
8+
m[word]++
9+
}
10+
pq := &PQ{}
11+
heap.Init(pq)
12+
for w, c := range m {
13+
heap.Push(pq, &wordCount{w, c})
14+
if pq.Len() > k {
15+
heap.Pop(pq)
16+
}
17+
}
18+
res := make([]string, k)
19+
for i := k - 1; i >= 0; i-- {
20+
wc := heap.Pop(pq).(*wordCount)
21+
res[i] = wc.word
22+
}
23+
return res
24+
}
25+
26+
type wordCount struct {
27+
word string
28+
cnt int
29+
}
30+
31+
type PQ []*wordCount
32+
33+
func (pq PQ) Len() int { return len(pq) }
34+
func (pq PQ) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] }
35+
func (pq PQ) Less(i, j int) bool {
36+
if pq[i].cnt == pq[j].cnt {
37+
return pq[i].word > pq[j].word
38+
}
39+
return pq[i].cnt < pq[j].cnt
40+
}
41+
func (pq *PQ) Push(x interface{}) {
42+
tmp := x.(*wordCount)
43+
*pq = append(*pq, tmp)
44+
}
45+
func (pq *PQ) Pop() interface{} {
46+
n := len(*pq)
47+
tmp := (*pq)[n-1]
48+
*pq = (*pq)[:n-1]
49+
return tmp
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package leetcode
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
type question692 struct {
9+
para692
10+
ans692
11+
}
12+
13+
// para 是参数
14+
// one 代表第一个参数
15+
type para692 struct {
16+
words []string
17+
k int
18+
}
19+
20+
// ans 是答案
21+
// one 代表第一个答案
22+
type ans692 struct {
23+
one []string
24+
}
25+
26+
func Test_Problem692(t *testing.T) {
27+
28+
qs := []question692{
29+
30+
{
31+
para692{[]string{"i", "love", "leetcode", "i", "love", "coding"}, 2},
32+
ans692{[]string{"i", "love"}},
33+
},
34+
35+
{
36+
para692{[]string{"the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"}, 4},
37+
ans692{[]string{"the", "is", "sunny", "day"}},
38+
},
39+
}
40+
41+
fmt.Printf("------------------------Leetcode Problem 692------------------------\n")
42+
43+
for _, q := range qs {
44+
_, p := q.ans692, q.para692
45+
fmt.Printf("【input】:%v 【output】:%v\n", p, topKFrequent(p.words, p.k))
46+
}
47+
fmt.Printf("\n\n\n")
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# [692. Top K Frequent Words](https://leetcode.com/problems/top-k-frequent-words/)
2+
3+
4+
## 题目
5+
6+
Given a non-empty list of words, return the k most frequent elements.
7+
8+
Your answer should be sorted by frequency from highest to lowest. If two words have the same frequency, then the word with the lower alphabetical order comes first.
9+
10+
**Example 1:**
11+
12+
```
13+
Input: ["i", "love", "leetcode", "i", "love", "coding"], k = 2
14+
Output: ["i", "love"]
15+
Explanation: "i" and "love" are the two most frequent words.
16+
Note that "i" comes before "love" due to a lower alphabetical order.
17+
```
18+
19+
**Example 2:**
20+
21+
```
22+
Input: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4
23+
Output: ["the", "is", "sunny", "day"]
24+
Explanation: "the", "is", "sunny" and "day" are the four most frequent words,
25+
with the number of occurrence being 4, 3, 2 and 1 respectively.
26+
```
27+
28+
**Note:**
29+
30+
1. You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
31+
2. Input words contain only lowercase letters.
32+
33+
**Follow up:**
34+
35+
1. Try to solve it in O(n log k) time and O(n) extra space.
36+
37+
## 题目大意
38+
39+
给一非空的单词列表,返回前 *k* 个出现次数最多的单词。返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。
40+
41+
## 解题思路
42+
43+
- 思路很简单的题。维护一个长度为 k 的最大堆,先按照频率排,如果频率相同再按照字母顺序排。最后输出依次将优先队列里面的元素 pop 出来即可。
44+
45+
## 代码
46+
47+
```go
48+
package leetcode
49+
50+
import "container/heap"
51+
52+
func topKFrequent(words []string, k int) []string {
53+
m := map[string]int{}
54+
for _, word := range words {
55+
m[word]++
56+
}
57+
pq := &PQ{}
58+
heap.Init(pq)
59+
for w, c := range m {
60+
heap.Push(pq, &wordCount{w, c})
61+
if pq.Len() > k {
62+
heap.Pop(pq)
63+
}
64+
}
65+
res := make([]string, k)
66+
for i := k - 1; i >= 0; i-- {
67+
wc := heap.Pop(pq).(*wordCount)
68+
res[i] = wc.word
69+
}
70+
return res
71+
}
72+
73+
type wordCount struct {
74+
word string
75+
cnt int
76+
}
77+
78+
type PQ []*wordCount
79+
80+
func (pq PQ) Len() int { return len(pq) }
81+
func (pq PQ) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] }
82+
func (pq PQ) Less(i, j int) bool {
83+
if pq[i].cnt == pq[j].cnt {
84+
return pq[i].word > pq[j].word
85+
}
86+
return pq[i].cnt < pq[j].cnt
87+
}
88+
func (pq *PQ) Push(x interface{}) {
89+
tmp := x.(*wordCount)
90+
*pq = append(*pq, tmp)
91+
}
92+
func (pq *PQ) Pop() interface{} {
93+
n := len(*pq)
94+
tmp := (*pq)[n-1]
95+
*pq = (*pq)[:n-1]
96+
return tmp
97+
}
98+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package leetcode
2+
3+
func findAndReplacePattern(words []string, pattern string) []string {
4+
res := make([]string, 0)
5+
for _, word := range words {
6+
if match(word, pattern) {
7+
res = append(res, word)
8+
}
9+
}
10+
return res
11+
}
12+
13+
func match(w, p string) bool {
14+
if len(w) != len(p) {
15+
return false
16+
}
17+
m, used := make(map[uint8]uint8), make(map[uint8]bool)
18+
for i := 0; i < len(w); i++ {
19+
if v, ok := m[p[i]]; ok {
20+
if w[i] != v {
21+
return false
22+
}
23+
} else {
24+
if used[w[i]] {
25+
return false
26+
}
27+
m[p[i]] = w[i]
28+
used[w[i]] = true
29+
}
30+
}
31+
return true
32+
}

0 commit comments

Comments
 (0)