Skip to content

Commit 8d52cc8

Browse files
authored
feat: add solutions to lc problem: No.3076 (doocs#2439)
No.3076.Shortest Uncommon Substring in an Array
1 parent a0960c4 commit 8d52cc8

File tree

9 files changed

+372
-10
lines changed

9 files changed

+372
-10
lines changed

solution/2600-2699/2674.Split a Circular Linked List/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646

4747
### 方法一:快慢指针
4848

49-
我们定义两个指针 $a$ 和 $b$,初始时都指向链表的头节点。每次迭代时,$a$ 指针向前移动一步,$b$ 指针向前移动两步,直到 $b$ 指针到达链表的末尾。此时,$a$ 指针指向链表节点数的一半,我们将链表从 $a$ 指针处断开,即可得到两个链表的头节点。
49+
我们定义两个指针 $a$ 和 $b$,初始时都指向链表的头节点。每次迭代时,指针 $a$ 向前移动一步,指针 $b$ 向前移动两步,直到指针 $b$ 到达链表的末尾。此时,指针 $a$ 指向链表节点数的一半,我们将链表从指针 $a$ 处断开,即可得到两个链表的头节点。
5050

5151
时间复杂度 $O(n)$,其中 $n$ 是链表的长度。需要遍历链表一次。空间复杂度 $O(1)$。
5252

solution/2600-2699/2674.Split a Circular Linked List/README_EN.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,11 @@
4040

4141
## Solutions
4242

43-
### Solution 1
43+
### Solution 1: Fast and Slow Pointers
44+
45+
We define two pointers $a$ and $b$, both initially pointing to the head of the linked list. Each iteration, pointer $a$ moves forward one step, and pointer $b$ moves forward two steps, until pointer $b$ reaches the end of the linked list. At this point, pointer $a$ points to half of the linked list nodes, and we break the linked list from pointer $a$, thus obtaining the head nodes of the two linked lists.
46+
47+
The time complexity is $O(n)$, where $n$ is the length of the linked list. It requires one traversal of the linked list. The space complexity is $O(1)$.
4448

4549
<!-- tabs:start -->
4650

solution/3000-3099/3076.Shortest Uncommon Substring in an Array/README.md

+125-4
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,145 @@
5656

5757
## 解法
5858

59-
### 方法一
59+
### 方法一:枚举
60+
61+
我们注意到数据规模很小,所以可以直接枚举每个字符串的所有子串,然后判断是否是其他字符串的子串。
62+
63+
具体地,我们先枚举每个字符串 `arr[i]`,然后从小到大枚举每个子串的长度 $j$,然后枚举每个子串的起始位置 $l$,可以得到当前子串为 `sub = arr[i][l:l+j]`,然后判断 `sub` 是否是其他字符串的子串,如果是的话,就跳过当前子串,否则更新答案。
64+
65+
时间复杂度 $O(n^2 \times m^4)$,空间复杂度 $O(m)$。其中 $n$ 是字符串数组 `arr` 的长度,而 $m$ 是字符串的最大长度,本题中 $m \le 20$。
6066

6167
<!-- tabs:start -->
6268

6369
```python
64-
70+
class Solution:
71+
def shortestSubstrings(self, arr: List[str]) -> List[str]:
72+
ans = [""] * len(arr)
73+
for i, s in enumerate(arr):
74+
m = len(s)
75+
for j in range(1, m + 1):
76+
for l in range(m - j + 1):
77+
sub = s[l : l + j]
78+
if not ans[i] or ans[i] > sub:
79+
if all(k == i or sub not in t for k, t in enumerate(arr)):
80+
ans[i] = sub
81+
if ans[i]:
82+
break
83+
return ans
6584
```
6685

6786
```java
68-
87+
class Solution {
88+
public String[] shortestSubstrings(String[] arr) {
89+
int n = arr.length;
90+
String[] ans = new String[n];
91+
Arrays.fill(ans, "");
92+
for (int i = 0; i < n; ++i) {
93+
int m = arr[i].length();
94+
for (int j = 1; j <= m && ans[i].isEmpty(); ++j) {
95+
for (int l = 0; l <= m - j; ++l) {
96+
String sub = arr[i].substring(l, l + j);
97+
if (ans[i].isEmpty() || sub.compareTo(ans[i]) < 0) {
98+
boolean ok = true;
99+
for (int k = 0; k < n && ok; ++k) {
100+
if (k != i && arr[k].contains(sub)) {
101+
ok = false;
102+
}
103+
}
104+
if (ok) {
105+
ans[i] = sub;
106+
}
107+
}
108+
}
109+
}
110+
}
111+
return ans;
112+
}
113+
}
69114
```
70115

71116
```cpp
72-
117+
class Solution {
118+
public:
119+
vector<string> shortestSubstrings(vector<string>& arr) {
120+
int n = arr.size();
121+
vector<string> ans(n);
122+
for (int i = 0; i < n; ++i) {
123+
int m = arr[i].size();
124+
for (int j = 1; j <= m && ans[i].empty(); ++j) {
125+
for (int l = 0; l <= m - j; ++l) {
126+
string sub = arr[i].substr(l, j);
127+
if (ans[i].empty() || sub < ans[i]) {
128+
bool ok = true;
129+
for (int k = 0; k < n && ok; ++k) {
130+
if (k != i && arr[k].find(sub) != string::npos) {
131+
ok = false;
132+
}
133+
}
134+
if (ok) {
135+
ans[i] = sub;
136+
}
137+
}
138+
}
139+
}
140+
}
141+
return ans;
142+
}
143+
};
73144
```
74145
75146
```go
147+
func shortestSubstrings(arr []string) []string {
148+
ans := make([]string, len(arr))
149+
for i, s := range arr {
150+
m := len(s)
151+
for j := 1; j <= m && len(ans[i]) == 0; j++ {
152+
for l := 0; l <= m-j; l++ {
153+
sub := s[l : l+j]
154+
if len(ans[i]) == 0 || ans[i] > sub {
155+
ok := true
156+
for k, t := range arr {
157+
if k != i && strings.Contains(t, sub) {
158+
ok = false
159+
break
160+
}
161+
}
162+
if ok {
163+
ans[i] = sub
164+
}
165+
}
166+
}
167+
}
168+
}
169+
return ans
170+
}
171+
```
76172

173+
```ts
174+
function shortestSubstrings(arr: string[]): string[] {
175+
const n: number = arr.length;
176+
const ans: string[] = Array(n).fill('');
177+
for (let i = 0; i < n; ++i) {
178+
const m: number = arr[i].length;
179+
for (let j = 1; j <= m && ans[i] === ''; ++j) {
180+
for (let l = 0; l <= m - j; ++l) {
181+
const sub: string = arr[i].slice(l, l + j);
182+
if (ans[i] === '' || sub.localeCompare(ans[i]) < 0) {
183+
let ok: boolean = true;
184+
for (let k = 0; k < n && ok; ++k) {
185+
if (k !== i && arr[k].includes(sub)) {
186+
ok = false;
187+
}
188+
}
189+
if (ok) {
190+
ans[i] = sub;
191+
}
192+
}
193+
}
194+
}
195+
}
196+
return ans;
197+
}
77198
```
78199

79200
<!-- tabs:end -->

solution/3000-3099/3076.Shortest Uncommon Substring in an Array/README_EN.md

+125-4
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,145 @@
5252

5353
## Solutions
5454

55-
### Solution 1
55+
### Solution 1: Enumeration
56+
57+
Given the small data scale, we can directly enumerate all substrings of each string and then determine whether it is a substring of other strings.
58+
59+
Specifically, we first enumerate each string `arr[i]`, then enumerate the length $j$ of each substring from small to large, and then enumerate the starting position $l$ of each substring. We can get the current substring as `sub = arr[i][l:l+j]`. Then we determine whether `sub` is a substring of other strings. If it is, we skip the current substring; otherwise, we update the answer.
60+
61+
The time complexity is $O(n^2 \times m^4)$, and the space complexity is $O(m)$. Where $n$ is the length of the string array `arr`, and $m$ is the maximum length of the string. In this problem, $m \le 20$.
5662

5763
<!-- tabs:start -->
5864

5965
```python
60-
66+
class Solution:
67+
def shortestSubstrings(self, arr: List[str]) -> List[str]:
68+
ans = [""] * len(arr)
69+
for i, s in enumerate(arr):
70+
m = len(s)
71+
for j in range(1, m + 1):
72+
for l in range(m - j + 1):
73+
sub = s[l : l + j]
74+
if not ans[i] or ans[i] > sub:
75+
if all(k == i or sub not in t for k, t in enumerate(arr)):
76+
ans[i] = sub
77+
if ans[i]:
78+
break
79+
return ans
6180
```
6281

6382
```java
64-
83+
class Solution {
84+
public String[] shortestSubstrings(String[] arr) {
85+
int n = arr.length;
86+
String[] ans = new String[n];
87+
Arrays.fill(ans, "");
88+
for (int i = 0; i < n; ++i) {
89+
int m = arr[i].length();
90+
for (int j = 1; j <= m && ans[i].isEmpty(); ++j) {
91+
for (int l = 0; l <= m - j; ++l) {
92+
String sub = arr[i].substring(l, l + j);
93+
if (ans[i].isEmpty() || sub.compareTo(ans[i]) < 0) {
94+
boolean ok = true;
95+
for (int k = 0; k < n && ok; ++k) {
96+
if (k != i && arr[k].contains(sub)) {
97+
ok = false;
98+
}
99+
}
100+
if (ok) {
101+
ans[i] = sub;
102+
}
103+
}
104+
}
105+
}
106+
}
107+
return ans;
108+
}
109+
}
65110
```
66111

67112
```cpp
68-
113+
class Solution {
114+
public:
115+
vector<string> shortestSubstrings(vector<string>& arr) {
116+
int n = arr.size();
117+
vector<string> ans(n);
118+
for (int i = 0; i < n; ++i) {
119+
int m = arr[i].size();
120+
for (int j = 1; j <= m && ans[i].empty(); ++j) {
121+
for (int l = 0; l <= m - j; ++l) {
122+
string sub = arr[i].substr(l, j);
123+
if (ans[i].empty() || sub < ans[i]) {
124+
bool ok = true;
125+
for (int k = 0; k < n && ok; ++k) {
126+
if (k != i && arr[k].find(sub) != string::npos) {
127+
ok = false;
128+
}
129+
}
130+
if (ok) {
131+
ans[i] = sub;
132+
}
133+
}
134+
}
135+
}
136+
}
137+
return ans;
138+
}
139+
};
69140
```
70141
71142
```go
143+
func shortestSubstrings(arr []string) []string {
144+
ans := make([]string, len(arr))
145+
for i, s := range arr {
146+
m := len(s)
147+
for j := 1; j <= m && len(ans[i]) == 0; j++ {
148+
for l := 0; l <= m-j; l++ {
149+
sub := s[l : l+j]
150+
if len(ans[i]) == 0 || ans[i] > sub {
151+
ok := true
152+
for k, t := range arr {
153+
if k != i && strings.Contains(t, sub) {
154+
ok = false
155+
break
156+
}
157+
}
158+
if ok {
159+
ans[i] = sub
160+
}
161+
}
162+
}
163+
}
164+
}
165+
return ans
166+
}
167+
```
72168

169+
```ts
170+
function shortestSubstrings(arr: string[]): string[] {
171+
const n: number = arr.length;
172+
const ans: string[] = Array(n).fill('');
173+
for (let i = 0; i < n; ++i) {
174+
const m: number = arr[i].length;
175+
for (let j = 1; j <= m && ans[i] === ''; ++j) {
176+
for (let l = 0; l <= m - j; ++l) {
177+
const sub: string = arr[i].slice(l, l + j);
178+
if (ans[i] === '' || sub.localeCompare(ans[i]) < 0) {
179+
let ok: boolean = true;
180+
for (let k = 0; k < n && ok; ++k) {
181+
if (k !== i && arr[k].includes(sub)) {
182+
ok = false;
183+
}
184+
}
185+
if (ok) {
186+
ans[i] = sub;
187+
}
188+
}
189+
}
190+
}
191+
}
192+
return ans;
193+
}
73194
```
74195

75196
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution {
2+
public:
3+
vector<string> shortestSubstrings(vector<string>& arr) {
4+
int n = arr.size();
5+
vector<string> ans(n);
6+
for (int i = 0; i < n; ++i) {
7+
int m = arr[i].size();
8+
for (int j = 1; j <= m && ans[i].empty(); ++j) {
9+
for (int l = 0; l <= m - j; ++l) {
10+
string sub = arr[i].substr(l, j);
11+
if (ans[i].empty() || sub < ans[i]) {
12+
bool ok = true;
13+
for (int k = 0; k < n && ok; ++k) {
14+
if (k != i && arr[k].find(sub) != string::npos) {
15+
ok = false;
16+
}
17+
}
18+
if (ok) {
19+
ans[i] = sub;
20+
}
21+
}
22+
}
23+
}
24+
}
25+
return ans;
26+
}
27+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
func shortestSubstrings(arr []string) []string {
2+
ans := make([]string, len(arr))
3+
for i, s := range arr {
4+
m := len(s)
5+
for j := 1; j <= m && len(ans[i]) == 0; j++ {
6+
for l := 0; l <= m-j; l++ {
7+
sub := s[l : l+j]
8+
if len(ans[i]) == 0 || ans[i] > sub {
9+
ok := true
10+
for k, t := range arr {
11+
if k != i && strings.Contains(t, sub) {
12+
ok = false
13+
break
14+
}
15+
}
16+
if ok {
17+
ans[i] = sub
18+
}
19+
}
20+
}
21+
}
22+
}
23+
return ans
24+
}

0 commit comments

Comments
 (0)