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 a2fb870

Browse files
feat: add solutions to lc problem: No.2868 (#1723)
No.2868.The Wording Game
1 parent 519ff75 commit a2fb870

File tree

11 files changed

+640
-0
lines changed

11 files changed

+640
-0
lines changed
Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
# [2868. 单词游戏](https://leetcode.cn/problems/the-wording-game)
2+
3+
[English Version](/solution/2800-2899/2868.The%20Wording%20Game/README_EN.md)
4+
5+
## 题目描述
6+
7+
<!-- 这里写题目描述 -->
8+
9+
<p>Alice 和 Bob 分别拥有一个&nbsp;<strong>按字典序排序&nbsp;</strong>的字符串数组,分别命名为 <code>a</code>&nbsp;和 <code>b</code>。</p>
10+
11+
<p>他们正在玩一个单词游戏,遵循以下规则:</p>
12+
13+
<ul>
14+
<li>每一轮,当前玩家应该从他的列表中选择一个单词,并且选择的单词比上一个单词 <strong>严格大</strong>;然后轮到另一名玩家。</li>
15+
<li>如果一名玩家在自己的回合中无法选择单词,则输掉比赛。</li>
16+
</ul>
17+
18+
<p>Alice 通过选择在 <strong>字典序最小</strong> 的单词开始游戏。</p>
19+
20+
<p>给定 <code>a</code> 和 <code>b</code>,已知两名玩家都按最佳策略玩游戏,如果 Alice 可以获胜,则返回 <code>true</code>&nbsp;,否则返回 <code>false</code>。</p>
21+
22+
<p>如果满足以下条件,则称一个单词 <code>w</code>&nbsp;比另一个单词 <code>z</code>&nbsp;<strong>严格大</strong>:</p>
23+
24+
<ul>
25+
<li><code>w</code> 在&nbsp;<strong>字典序上大于</strong> <code>z</code>。</li>
26+
<li>如果 <code>w<sub>1</sub></code> 是 <code>w</code> 的第一个字母,<code>z<sub>1</sub></code> 是 <code>z</code> 的第一个字母,那么 <code>w<sub>1</sub></code> 应该 <strong>等于</strong> <code>z<sub>1</sub></code> 或者是字母表中 <code>z<sub>1</sub></code> <strong>后面相邻&nbsp;</strong>的字母。</li>
27+
<li>例如,单词 <code>"care"</code>&nbsp;比&nbsp;<code>"book"</code> 和 <code>"car"</code>&nbsp;严格大,但不比&nbsp;<code>"ant"</code> 或 <code>"cook"</code>&nbsp;严格大。</li>
28+
</ul>
29+
30+
<p>如果在 <code>s</code> 和 <code>t</code> 不同的第一个位置处,字符串 <code>s</code>&nbsp;的字母比字符串 <code>t</code>&nbsp;的字母在字母表中的顺序更靠后,则称为字符串 <code>s</code> 在 <strong>字典序上大于</strong> 字符串 <code>t</code>。如果前 <code>min(s.length, t.length)</code> 个字符没有区别,那么较长的字符串是在字典序上较大的那一个。</p>
31+
32+
<p>&nbsp;</p>
33+
34+
<p><strong>示例 1:</strong></p>
35+
36+
<pre>
37+
<strong>输入:</strong> a = ["avokado","dabar"], b = ["brazil"]
38+
39+
<strong>输出:</strong> false
40+
41+
<strong>解释:</strong> Alice 必须从单词 "avokado" 来开始游戏,因为这是她最小的单词,然后 Bob 使用他唯一的单词 "brazil",他可以使用它因为它的第一个字母 'b' 在 Alice 的单词的第一个字母 'a' 之后。
42+
43+
Alice 无法出牌,因为剩下的唯一单词的第一个字母既不等于 'b' 也不是 'b' 之后的字母 'c'。
44+
45+
所以,Alice 输了,游戏结束。</pre>
46+
47+
<strong>示例 2:</strong>
48+
49+
<pre>
50+
<strong>输入:</strong> a = ["ananas","atlas","banana"], b = ["albatros","cikla","nogomet"]
51+
52+
<strong>输出:</strong> true
53+
54+
<strong>解释:</strong> Alice 必须从单词 "ananas" 来开始游戏。
55+
56+
Bob 无法出牌,因为他唯一拥有的以字母 'a' 或 'b' 开头的单词是 "albatros",而它比 Alice 的单词小。
57+
58+
所以,Alice 获胜,游戏结束。</pre>
59+
60+
<strong>示例 3:</strong>
61+
62+
<pre>
63+
<strong>输入:</strong> a = ["hrvatska","zastava"], b = ["bijeli","galeb"]
64+
65+
<strong>输出:</strong> true
66+
67+
<strong>解释:</strong> Alice 必须从单词 "hrvatska" 来开始游戏。
68+
69+
Bob 无法出牌,因为他的两个单词的第一个字母都比 Alice 的单词的第一个字母 'h' 小。
70+
71+
所以,Alice 获胜,游戏结束。</pre>
72+
73+
<p>&nbsp;</p>
74+
75+
<p><strong>约束条件:</strong></p>
76+
77+
<ul>
78+
<li><code>1 &lt;= a.length, b.length &lt;= 10<sup>5</sup></code></li>
79+
<li><code>a[i]</code> 和 <code>b[i]</code> 仅包含小写英文字母。</li>
80+
<li><code>a</code> 和 <code>b</code> 按 <strong>字典序排序</strong>。</li>
81+
<li><code>a</code> 和 <code>b</code> 中所有的单词都是&nbsp;<strong>不同的</strong>。</li>
82+
<li><code>a</code> 和 <code>b</code> 中所有单词的长度之和不超过 <code>10<sup>6</sup></code>。</li>
83+
</ul>
84+
85+
## 解法
86+
87+
<!-- 这里可写通用的实现逻辑 -->
88+
89+
**方法一:模拟**
90+
91+
我们记当前轮到 $Alice$ 的回合为 $k=0,ドル轮到 $Bob$ 的回合为 $k=1$。我们用 $i$ 记录 $Alice$ 的下标,用 $j$ 记录 $Bob$ 的下标,用 $w$ 记录当前轮到的玩家的单词。初始时 $i=1,ドル $j=0,ドル $w=a[0]$。
92+
93+
我们不断地进行如下操作:
94+
95+
如果 $k=1,ドル则我们判断 $j$ 是否等于 $b$ 的长度,如果等于则说明 $Alice$ 获胜,返回 $true$;否则我们判断 $b[j]$ 的第一个字母是否等于 $w$ 的第一个字母,如果等于则我们判断 $b[j]$ 是否大于 $w,ドル或者 $b[j]$ 的第一个字母是否比 $w$ 的第一个字母大 1ドル,ドル如果是则说明 $Bob$ 可以出第 $j$ 个单词,我们令 $w=b[j],ドル并将 $k$ 取反;否则说明 $Bob$ 无法出第 $j$ 个单词,我们令 $j$ 加一。
96+
97+
如果 $k=0,ドル则我们判断 $i$ 是否等于 $a$ 的长度,如果等于则说明 $Bob$ 获胜,返回 $false$;否则我们判断 $a[i]$ 的第一个字母是否等于 $w$ 的第一个字母,如果等于则我们判断 $a[i]$ 是否大于 $w,ドル或者 $a[i]$ 的第一个字母是否比 $w$ 的第一个字母大 1ドル,ドル如果是则说明 $Alice$ 可以出第 $i$ 个单词,我们令 $w=a[i],ドル并将 $k$ 取反;否则说明 $Alice$ 无法出第 $i$ 个单词,我们令 $i$ 加一。
98+
99+
时间复杂度 $O(m + n),ドル其中 $m$ 和 $n$ 分别是数组 $a$ 和 $b$ 的长度。我们只需要遍历数组一次。空间复杂度 $O(1)$。
100+
101+
<!-- tabs:start -->
102+
103+
### **Python3**
104+
105+
<!-- 这里可写当前语言的特殊实现逻辑 -->
106+
107+
```python
108+
class Solution:
109+
def canAliceWin(self, a: List[str], b: List[str]) -> bool:
110+
i, j, k = 1, 0, 1
111+
w = a[0]
112+
while 1:
113+
if k:
114+
if j == len(b):
115+
return True
116+
if (b[j][0] == w[0] and b[j] > w) or ord(b[j][0]) - ord(w[0]) == 1:
117+
w = b[j]
118+
k ^= 1
119+
j += 1
120+
else:
121+
if i == len(a):
122+
return False
123+
if (a[i][0] == w[0] and a[i] > w) or ord(a[i][0]) - ord(w[0]) == 1:
124+
w = a[i]
125+
k ^= 1
126+
i += 1
127+
```
128+
129+
### **Java**
130+
131+
<!-- 这里可写当前语言的特殊实现逻辑 -->
132+
133+
```java
134+
class Solution {
135+
public boolean canAliceWin(String[] a, String[] b) {
136+
int i = 1, j = 0;
137+
boolean k = true;
138+
String w = a[0];
139+
while (true) {
140+
if (k) {
141+
if (j == b.length) {
142+
return true;
143+
}
144+
if ((b[j].charAt(0) == w.charAt(0) && w.compareTo(b[j]) < 0)
145+
|| b[j].charAt(0) - w.charAt(0) == 1) {
146+
w = b[j];
147+
k = !k;
148+
}
149+
++j;
150+
} else {
151+
if (i == a.length) {
152+
return false;
153+
}
154+
if ((a[i].charAt(0) == w.charAt(0) && w.compareTo(a[i]) < 0)
155+
|| a[i].charAt(0) - w.charAt(0) == 1) {
156+
w = a[i];
157+
k = !k;
158+
}
159+
++i;
160+
}
161+
}
162+
}
163+
}
164+
```
165+
166+
### **C++**
167+
168+
```cpp
169+
class Solution {
170+
public:
171+
bool canAliceWin(vector<string>& a, vector<string>& b) {
172+
int i = 1, j = 0, k = 1;
173+
string w = a[0];
174+
while (1) {
175+
if (k) {
176+
if (j == b.size()) {
177+
return true;
178+
}
179+
if ((b[j][0] == w[0] && w < b[j]) || b[j][0] - w[0] == 1) {
180+
w = b[j];
181+
k ^= 1;
182+
}
183+
++j;
184+
} else {
185+
if (i == a.size()) {
186+
return false;
187+
}
188+
if ((a[i][0] == w[0] && w < a[i]) || a[i][0] - w[0] == 1) {
189+
w = a[i];
190+
k ^= 1;
191+
}
192+
++i;
193+
}
194+
}
195+
}
196+
};
197+
```
198+
199+
### **Go**
200+
201+
```go
202+
func canAliceWin(a []string, b []string) bool {
203+
i, j, k := 1, 0, 1
204+
w := a[0]
205+
for {
206+
if k&1 == 1 {
207+
if j == len(b) {
208+
return true
209+
}
210+
if (b[j][0] == w[0] && w < b[j]) || b[j][0]-w[0] == 1 {
211+
w = b[j]
212+
k ^= 1
213+
}
214+
j++
215+
} else {
216+
if i == len(a) {
217+
return false
218+
}
219+
if (a[i][0] == w[0] && w < a[i]) || a[i][0]-w[0] == 1 {
220+
w = a[i]
221+
k ^= 1
222+
}
223+
i++
224+
}
225+
}
226+
}
227+
```
228+
229+
### **TypeScript**
230+
231+
```ts
232+
function canAliceWin(a: string[], b: string[]): boolean {
233+
let [i, j, k] = [1, 0, 1];
234+
let w = a[0];
235+
while (1) {
236+
if (k) {
237+
if (j === b.length) {
238+
return true;
239+
}
240+
if ((b[j][0] === w[0] && w < b[j]) || b[j].charCodeAt(0) - w.charCodeAt(0) === 1) {
241+
w = b[j];
242+
k ^= 1;
243+
}
244+
++j;
245+
} else {
246+
if (i === a.length) {
247+
return false;
248+
}
249+
if ((a[i][0] === w[0] && w < a[i]) || a[i].charCodeAt(0) - w.charCodeAt(0) === 1) {
250+
w = a[i];
251+
k ^= 1;
252+
}
253+
++i;
254+
}
255+
}
256+
}
257+
```
258+
259+
### **...**
260+
261+
```
262+
263+
```
264+
265+
<!-- tabs:end -->

0 commit comments

Comments
(0)

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