Skip to content

Commit a2fb870

Browse files
authored
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
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)