|
5 | 5 | ## 题目描述
|
6 | 6 |
|
7 | 7 | <!-- 这里写题目描述 -->
|
| 8 | + |
8 | 9 | <p>设计一个算法,判断玩家是否赢了井字游戏。输入是一个 N x N 的数组棋盘,由字符" ","X"和"O"组成,其中字符" "代表一个空位。</p>
|
9 | 10 | <p>以下是井字游戏的规则:</p>
|
10 | 11 | <ul>
|
|
39 | 40 | ## 解法
|
40 | 41 |
|
41 | 42 | <!-- 这里可写通用的实现逻辑 -->
|
| 43 | + |
| 44 | +**方法一:计数** |
| 45 | + |
| 46 | +对于每个格子,如果是 `X`,我们不妨将计数加 $1$,如果是 `O`,我们不妨将计数减 $1$。那么当某个格子所在的行、列或者对角线的计数的绝对值等于 $n$ 时,说明当前玩家在该行、列或者对角线上放置了 $n$ 个相同字符,游戏结束,返回对应的字符即可。 |
| 47 | + |
| 48 | +具体地,我们用一个长度为 $n$ 的一维数组 $rows$ 和 $cols$ 分别表示每一行和每一列的计数,用 $dg$ 和 $udg$ 分别表示两个对角线的计数。当玩家放置一个字符到 $(i, j)$ 时,根据字符是 `X` 还是 `O`,更新数组 $rows$,$cols$,$dg$ 以及 $udg$ 中对应元素的值。每次更新后,我们判断对应的元素的值的绝对值是否等于 $n$,如果等于 $n$,则说明当前玩家在行、列或者对角线上放置了 $n$ 个相同字符,游戏结束,返回对应的字符即可。 |
| 49 | + |
| 50 | +最后,我们遍历整个棋盘,如果棋盘中存在字符 ` `,说明游戏还未结束,返回 `Pending`,否则返回 `Draw`。 |
| 51 | + |
| 52 | +时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 是棋盘的边长。 |
| 53 | + |
42 | 54 | <!-- tabs:start -->
|
43 | 55 |
|
44 | 56 | ### **Python3**
|
45 | 57 |
|
46 | 58 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
47 | 59 |
|
48 | 60 | ```python
|
49 |
| - |
| 61 | +class Solution: |
| 62 | + def tictactoe(self, board: List[str]) -> str: |
| 63 | + n = len(board) |
| 64 | + rows = [0] * n |
| 65 | + cols = [0] * n |
| 66 | + dg = udg = 0 |
| 67 | + has_empty_grid = False |
| 68 | + for i, row in enumerate(board): |
| 69 | + for j, c in enumerate(row): |
| 70 | + v = 1 if c == 'X' else -1 |
| 71 | + if c == ' ': |
| 72 | + has_empty_grid = True |
| 73 | + v = 0 |
| 74 | + rows[i] += v |
| 75 | + cols[j] += v |
| 76 | + if i == j: |
| 77 | + dg += v |
| 78 | + if i + j + 1 == n: |
| 79 | + udg += v |
| 80 | + if abs(rows[i]) == n or abs(cols[j]) == n or abs(dg) == n or abs(udg) == n: |
| 81 | + return c |
| 82 | + return 'Pending' if has_empty_grid else 'Draw' |
50 | 83 | ```
|
51 | 84 |
|
52 | 85 | ### **Java**
|
53 | 86 |
|
54 | 87 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
55 | 88 |
|
56 | 89 | ```java
|
| 90 | +class Solution { |
| 91 | + public String tictactoe(String[] board) { |
| 92 | + int n = board.length; |
| 93 | + int[] rows = new int[n]; |
| 94 | + int[] cols = new int[n]; |
| 95 | + int dg = 0, udg = 0; |
| 96 | + boolean hasEmptyGrid = false; |
| 97 | + for (int i = 0; i < n; ++i) { |
| 98 | + for (int j = 0; j < n; ++j) { |
| 99 | + char c = board[i].charAt(j); |
| 100 | + if (c == ' ') { |
| 101 | + hasEmptyGrid = true; |
| 102 | + continue; |
| 103 | + } |
| 104 | + int v = c == 'X' ? 1 : -1; |
| 105 | + rows[i] += v; |
| 106 | + cols[j] += v; |
| 107 | + if (i == j) { |
| 108 | + dg += v; |
| 109 | + } |
| 110 | + if (i + j + 1 == n) { |
| 111 | + udg += v; |
| 112 | + } |
| 113 | + if (Math.abs(rows[i]) == n || Math.abs(cols[j]) == n || Math.abs(dg) == n |
| 114 | + || Math.abs(udg) == n) { |
| 115 | + return String.valueOf(c); |
| 116 | + } |
| 117 | + } |
| 118 | + } |
| 119 | + return hasEmptyGrid ? "Pending" : "Draw"; |
| 120 | + } |
| 121 | +} |
| 122 | +``` |
| 123 | + |
| 124 | +### **C++** |
| 125 | + |
| 126 | +```cpp |
| 127 | +class Solution { |
| 128 | +public: |
| 129 | + string tictactoe(vector<string>& board) { |
| 130 | + int n = board.size(); |
| 131 | + vector<int> rows(n), cols(n); |
| 132 | + int dg = 0, udg = 0; |
| 133 | + bool hasEmptyGrid = false; |
| 134 | + for (int i = 0; i < n; ++i) { |
| 135 | + for (int j = 0; j < n; ++j) { |
| 136 | + char c = board[i][j]; |
| 137 | + if (c == ' ') { |
| 138 | + hasEmptyGrid = true; |
| 139 | + continue; |
| 140 | + } |
| 141 | + int v = c == 'X' ? 1 : -1; |
| 142 | + rows[i] += v; |
| 143 | + cols[j] += v; |
| 144 | + if (i == j) { |
| 145 | + dg += v; |
| 146 | + } |
| 147 | + if (i + j + 1 == n) { |
| 148 | + udg += v; |
| 149 | + } |
| 150 | + if (abs(rows[i]) == n || abs(cols[j]) == n || abs(dg) == n || abs(udg) == n) { |
| 151 | + return string(1, c); |
| 152 | + } |
| 153 | + } |
| 154 | + } |
| 155 | + return hasEmptyGrid ? "Pending" : "Draw"; |
| 156 | + } |
| 157 | +}; |
| 158 | +``` |
| 159 | +
|
| 160 | +### **Go** |
| 161 | +
|
| 162 | +```go |
| 163 | +func tictactoe(board []string) string { |
| 164 | + n := len(board) |
| 165 | + rows := make([]int, n) |
| 166 | + cols := make([]int, n) |
| 167 | + dg, udg := 0, 0 |
| 168 | + hasEmptyGrid := false |
| 169 | + for i, row := range board { |
| 170 | + for j, c := range row { |
| 171 | + if c == ' ' { |
| 172 | + hasEmptyGrid = true |
| 173 | + continue |
| 174 | + } |
| 175 | + v := 1 |
| 176 | + if c == 'O' { |
| 177 | + v = -1 |
| 178 | + } |
| 179 | + rows[i] += v |
| 180 | + cols[j] += v |
| 181 | + if i == j { |
| 182 | + dg += v |
| 183 | + } |
| 184 | + if i+j == n-1 { |
| 185 | + udg += v |
| 186 | + } |
| 187 | + if abs(rows[i]) == n || abs(cols[j]) == n || abs(dg) == n || abs(udg) == n { |
| 188 | + return string(c) |
| 189 | + } |
| 190 | + } |
| 191 | + } |
| 192 | + if hasEmptyGrid { |
| 193 | + return "Pending" |
| 194 | + } |
| 195 | + return "Draw" |
| 196 | +} |
| 197 | +
|
| 198 | +func abs(x int) int { |
| 199 | + if x < 0 { |
| 200 | + return -x |
| 201 | + } |
| 202 | + return x |
| 203 | +} |
| 204 | +``` |
57 | 205 |
|
| 206 | +### **TypeScript** |
| 207 | + |
| 208 | +```ts |
| 209 | +function tictactoe(board: string[]): string { |
| 210 | + const n = board.length; |
| 211 | + const rows = Array(n).fill(0); |
| 212 | + const cols = Array(n).fill(0); |
| 213 | + let [dg, udg] = [0, 0]; |
| 214 | + let hasEmptyGrid = false; |
| 215 | + for (let i = 0; i < n; ++i) { |
| 216 | + for (let j = 0; j < n; ++j) { |
| 217 | + const c = board[i][j]; |
| 218 | + if (c === ' ') { |
| 219 | + hasEmptyGrid = true; |
| 220 | + continue; |
| 221 | + } |
| 222 | + const v = c === 'X' ? 1 : -1; |
| 223 | + rows[i] += v; |
| 224 | + cols[j] += v; |
| 225 | + if (i === j) { |
| 226 | + dg += v; |
| 227 | + } |
| 228 | + if (i + j === n - 1) { |
| 229 | + udg += v; |
| 230 | + } |
| 231 | + if ( |
| 232 | + Math.abs(rows[i]) === n || |
| 233 | + Math.abs(cols[j]) === n || |
| 234 | + Math.abs(dg) === n || |
| 235 | + Math.abs(udg) === n |
| 236 | + ) { |
| 237 | + return c; |
| 238 | + } |
| 239 | + } |
| 240 | + } |
| 241 | + return hasEmptyGrid ? 'Pending' : 'Draw'; |
| 242 | +} |
58 | 243 | ```
|
59 | 244 |
|
60 | 245 | ### **...**
|
|
0 commit comments