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 ec6cc34

Browse files
feat: add solutions to lcci problem: No.16.18 (#1653)
No.16.18.Pattern Matching
1 parent cfcc7e0 commit ec6cc34

File tree

8 files changed

+731
-1
lines changed

8 files changed

+731
-1
lines changed

‎lcci/16.18.Pattern Matching/README.md‎

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## 题目描述
66

77
<!-- 这里写题目描述 -->
8+
89
<p>你有两个字符串,即<code>pattern</code>和<code>value</code>。 <code>pattern</code>字符串由字母<code>"a"</code>和<code>"b"</code>组成,用于描述字符串中的模式。例如,字符串<code>"catcatgocatgo"</code>匹配模式<code>"aabab"</code>(其中<code>"cat"</code>是<code>"a"</code>,<code>"go"</code>是<code>"b"</code>),该字符串也匹配像<code>"a"</code>、<code>"ab"</code>和<code>"b"</code>这样的模式。但需注意<code>"a"</code>和<code>"b"</code>不能同时表示相同的字符串。编写一个方法判断<code>value</code>字符串是否匹配<code>pattern</code>字符串。</p>
910
<p><strong>示例 1:</strong></p>
1011
<pre><strong>输入:</strong> pattern = "abba", value = "dogcatcatdog"
@@ -33,22 +34,278 @@
3334
## 解法
3435

3536
<!-- 这里可写通用的实现逻辑 -->
37+
38+
**方法一:枚举**
39+
40+
我们先统计出模式串 $pattern$ 中 `'a'``'b'` 的个数,分别为 $cnt[0]$ 和 $cnt[1]$。记字符串 $value$ 的长度为 $n$。
41+
42+
如果 $cnt[0]=0,ドル说明模式串中只包含字符 `'b'`,那么我们需要判断 $n$ 是否是 $cnt[1]$ 的倍数,以及 $value$ 是否可以分割成 $cnt[1]$ 个长度为 $n/cnt[1]$ 的子串,且这些子串都相同。如果不满足,直接返回 $false$ 即可。
43+
44+
如果 $cnt[1]=0,ドル说明模式串中只包含字符 `'a'`,那么我们需要判断 $n$ 是否是 $cnt[0]$ 的倍数,以及 $value$ 是否可以分割成 $cnt[0]$ 个长度为 $n/cnt[0]$ 的子串,且这些子串都相同。如果不满足,直接返回 $false$ 即可。
45+
46+
接下来,我们记字符 `'a'` 所匹配的字符串的长度 $la,ドル字符 `'b'` 所匹配的字符串的长度 $lb$。那么有 $la \times cnt[0] + lb \times cnt[1] = n$。如果我们枚举 $la,ドル就可以知道 $lb$ 的值了。因此我们可以枚举 $la,ドル只需要判断是否存在一个整数 $lb,ドル满足上述等式即可。
47+
48+
时间复杂度 $O(n^2),ドル空间复杂度 $O(n)$。其中 $n$ 为字符串 $value$ 的长度。
49+
3650
<!-- tabs:start -->
3751

3852
### **Python3**
3953

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

4256
```python
57+
class Solution:
58+
def patternMatching(self, pattern: str, value: str) -> bool:
59+
def check(la: int, lb: int) -> bool:
60+
i = 0
61+
a, b = "", ""
62+
for c in pattern:
63+
if c == "a":
64+
if a and value[i : i + la] != a:
65+
return False
66+
a = value[i : i + la]
67+
i += la
68+
else:
69+
if b and value[i : i + lb] != b:
70+
return False
71+
b = value[i : i + lb]
72+
i += lb
73+
return a != b
4374

75+
n = len(value)
76+
cnt = Counter(pattern)
77+
if cnt["a"] == 0:
78+
return n % cnt["b"] == 0 and value[: n // cnt["b"]] * cnt["b"] == value
79+
if cnt["b"] == 0:
80+
return n % cnt["a"] == 0 and value[: n // cnt["a"]] * cnt["a"] == value
81+
82+
for la in range(n + 1):
83+
if la * cnt["a"] > n:
84+
break
85+
lb, mod = divmod(n - la * cnt["a"], cnt["b"])
86+
if mod == 0 and check(la, lb):
87+
return True
88+
return False
4489
```
4590

4691
### **Java**
4792

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

5095
```java
96+
class Solution {
97+
private String pattern;
98+
private String value;
99+
100+
public boolean patternMatching(String pattern, String value) {
101+
this.pattern = pattern;
102+
this.value = value;
103+
int[] cnt = new int[2];
104+
for (char c : pattern.toCharArray()) {
105+
++cnt[c - 'a'];
106+
}
107+
int n = value.length();
108+
if (cnt[0] == 0) {
109+
return n % cnt[1] == 0 && value.substring(0, n / cnt[1]).repeat(cnt[1]).equals(value);
110+
}
111+
if (cnt[1] == 0) {
112+
return n % cnt[0] == 0 && value.substring(0, n / cnt[0]).repeat(cnt[0]).equals(value);
113+
}
114+
for (int la = 0; la <= n; ++la) {
115+
if (la * cnt[0] > n) {
116+
break;
117+
}
118+
if ((n - la * cnt[0]) % cnt[1] == 0) {
119+
int lb = (n - la * cnt[0]) / cnt[1];
120+
if (check(la, lb)) {
121+
return true;
122+
}
123+
}
124+
}
125+
return false;
126+
}
127+
128+
private boolean check(int la, int lb) {
129+
int i = 0;
130+
String a = null, b = null;
131+
for (char c : pattern.toCharArray()) {
132+
if (c == 'a') {
133+
if (a != null && !a.equals(value.substring(i, i + la))) {
134+
return false;
135+
}
136+
a = value.substring(i, i + la);
137+
i += la;
138+
} else {
139+
if (b != null && !b.equals(value.substring(i, i + lb))) {
140+
return false;
141+
}
142+
b = value.substring(i, i + lb);
143+
i += lb;
144+
}
145+
}
146+
return !a.equals(b);
147+
}
148+
}
149+
```
150+
151+
### **C++**
152+
153+
```cpp
154+
class Solution {
155+
public:
156+
bool patternMatching(string pattern, string value) {
157+
int n = value.size();
158+
int cnt[2]{};
159+
for (char c : pattern) {
160+
cnt[c - 'a']++;
161+
}
162+
if (cnt[0] == 0) {
163+
return n % cnt[1] == 0 && repeat(value.substr(0, n / cnt[1]), cnt[1]) == value;
164+
}
165+
if (cnt[1] == 0) {
166+
return n % cnt[0] == 0 && repeat(value.substr(0, n / cnt[0]), cnt[0]) == value;
167+
}
168+
auto check = [&](int la, int lb) {
169+
int i = 0;
170+
string a, b;
171+
for (char c : pattern) {
172+
if (c == 'a') {
173+
if (!a.empty() && a != value.substr(i, la)) {
174+
return false;
175+
}
176+
a = value.substr(i, la);
177+
i += la;
178+
} else {
179+
if (!b.empty() && b != value.substr(i, lb)) {
180+
return false;
181+
}
182+
b = value.substr(i, lb);
183+
i += lb;
184+
}
185+
}
186+
return a != b;
187+
};
188+
for (int la = 0; la <= n; ++la) {
189+
if (la * cnt[0] > n) {
190+
break;
191+
}
192+
if ((n - la * cnt[0]) % cnt[1] == 0) {
193+
int lb = (n - la * cnt[0]) / cnt[1];
194+
if (check(la, lb)) {
195+
return true;
196+
}
197+
}
198+
}
199+
return false;
200+
}
201+
202+
string repeat(string s, int n) {
203+
string ans;
204+
while (n--) {
205+
ans += s;
206+
}
207+
return ans;
208+
}
209+
};
210+
```
211+
212+
### **Go**
213+
214+
```go
215+
func patternMatching(pattern string, value string) bool {
216+
cnt := [2]int{}
217+
for _, c := range pattern {
218+
cnt[c-'a']++
219+
}
220+
n := len(value)
221+
if cnt[0] == 0 {
222+
return n%cnt[1] == 0 && strings.Repeat(value[:n/cnt[1]], cnt[1]) == value
223+
}
224+
if cnt[1] == 0 {
225+
return n%cnt[0] == 0 && strings.Repeat(value[:n/cnt[0]], cnt[0]) == value
226+
}
227+
check := func(la, lb int) bool {
228+
i := 0
229+
a, b := "", ""
230+
for _, c := range pattern {
231+
if c == 'a' {
232+
if a != "" && value[i:i+la] != a {
233+
return false
234+
}
235+
a = value[i : i+la]
236+
i += la
237+
} else {
238+
if b != "" && value[i:i+lb] != b {
239+
return false
240+
}
241+
b = value[i : i+lb]
242+
i += lb
243+
}
244+
}
245+
return a != b
246+
}
247+
for la := 0; la <= n; la++ {
248+
if la*cnt[0] > n {
249+
break
250+
}
251+
if (n-la*cnt[0])%cnt[1] == 0 {
252+
lb := (n - la*cnt[0]) / cnt[1]
253+
if check(la, lb) {
254+
return true
255+
}
256+
}
257+
}
258+
return false
259+
}
260+
```
261+
262+
### **TypeScript**
51263

264+
```ts
265+
function patternMatching(pattern: string, value: string): boolean {
266+
const cnt: number[] = [0, 0];
267+
for (const c of pattern) {
268+
cnt[c === 'a' ? 0 : 1]++;
269+
}
270+
const n = value.length;
271+
if (cnt[0] === 0) {
272+
return n % cnt[1] === 0 && value.slice(0, (n / cnt[1]) | 0).repeat(cnt[1]) === value;
273+
}
274+
if (cnt[1] === 0) {
275+
return n % cnt[0] === 0 && value.slice(0, (n / cnt[0]) | 0).repeat(cnt[0]) === value;
276+
}
277+
const check = (la: number, lb: number) => {
278+
let i = 0;
279+
let a = '';
280+
let b = '';
281+
for (const c of pattern) {
282+
if (c === 'a') {
283+
if (a && a !== value.slice(i, i + la)) {
284+
return false;
285+
}
286+
a = value.slice(i, (i += la));
287+
} else {
288+
if (b && b !== value.slice(i, i + lb)) {
289+
return false;
290+
}
291+
b = value.slice(i, (i += lb));
292+
}
293+
}
294+
return a !== b;
295+
};
296+
for (let la = 0; la <= n; ++la) {
297+
if (la * cnt[0] > n) {
298+
break;
299+
}
300+
if ((n - la * cnt[0]) % cnt[1] === 0) {
301+
const lb = ((n - la * cnt[0]) / cnt[1]) | 0;
302+
if (check(la, lb)) {
303+
return true;
304+
}
305+
}
306+
}
307+
return false;
308+
}
52309
```
53310

54311
### **...**

0 commit comments

Comments
(0)

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