C++ 1275.cpp
class Solution {
public:
string tictactoe(vector<vector<int>>& moves) {
char board[3][3] = { { ' ', ' ', ' ' }, { ' ', ' ', ' ' }, { ' ', ' ', ' ' }};
for (auto i = 0; i < moves.size(); i++)
{
auto r = moves[i][0];
auto c = moves[i][1];
board[r][c] = (i & 1) ? 'B' : 'A';
}
for (int i = 0; i < 3; i++)
{
if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][0] == board[i][2])
return string(1, board[i][0]);
if (board[0][i] != ' ' && board[0][i] == board[1][i] && board[0][i] == board[2][i])
return string(1, board[0][i]);
if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[0][0] == board[2][2])
return string(1, board[0][0]);
if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[0][2] == board[2][0])
return string(1, board[0][2]);
}
if (moves.size() == 9)
return "Draw";
return "Pending";
}
};
Difficulty
and has an acceptance rate of about 55% (300k+ submissions).
Typical patterns to solve this problem:
- Array
- Hash Table
- Matrix
- Simulation
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The presented implementation determines the result of a Tic-Tac-Toe game given a sequence of moves. It builds an internal 3×3 board, fills it according to the move order, then checks all possible winning lines. Depending on the board state it returns "A" for player A, "B" for player B, "Draw" when the board is full without a winner, or "Pending" when moves remain.
Board Construction
The algorithm starts by allocating a fixed-size character matrix initialized with blanks.
char board[3][3] = { { ' ', ' ', ' ' },
{ ' ', ' ', ' ' },
{ ' ', ' ', ' ' } };
A simple loop iterates over the moves vector. For each move the row and column indices are extracted, and the board cell is set to 'A' or 'B' based on the parity of the move index.
for (auto i = 0; i < moves.size(); i++)
{
auto r = moves[i][0];
auto c = moves[i][1];
board[r][c] = (i & 1) ? 'B' : 'A';
}
The use of the bitwise & operator to test the least-significant bit provides a fast way to alternate between the two players without a conditional branch.
Winning Line Detection
After the board is populated, a single loop runs three times, using the loop variable as an index for rows and columns. Within each iteration the code checks four distinct patterns:
- Horizontal line in row
i. - Vertical line in column
i. - The main diagonal (checked repeatedly but harmless).
- The anti-diagonal (also checked repeatedly).
The checks are short-circuiting: they first verify that the starting cell is not blank, then compare the three cells for equality. When a winning line is found, the function returns a one-character string containing the winner’s symbol.
for (int i = 0; i < 3; i++)
{
if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][0] == board[i][2])
return string(1, board[i][0]);
if (board[0][i] != ' ' && board[0][i] == board[1][i] && board[0][i] == board[2][i])
return string(1, board[0][i]);
if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[0][0] == board[2][2])
return string(1, board[0][0]);
if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[0][2] == board[2][0])
return string(1, board[0][2]);
}
Because the board size is constant, the repeated diagonal checks do not affect overall efficiency, and they keep the code layout uniform.
Determining Draw or Pending
If no winner is detected, the function examines the total number of moves. A full board (nine moves) indicates a draw; otherwise the game is still in progress.
if (moves.size() == 9)
return "Draw";
return "Pending";
Edge Cases Handled
The implementation gracefully handles the situation where the move list is shorter than nine, returning "Pending" when no winning line exists. It also correctly identifies a win that occurs before the board is filled, because the win detection runs after all moves have been placed, regardless of move count. The alternating player assignment using the index parity ensures that even if the input contains an odd number of moves, the correct player symbols are placed.
When the input contains exactly nine moves without a winner, the final conditional returns "Draw". The code also tolerates an empty move list: the board remains blank, the win checks find no matches, and the size check falls through to "Pending".
Performance Optimizations
The algorithm uses a statically sized array for the board, avoiding dynamic allocation and the overhead of container classes. The board is populated in a single pass over the input vector, and the win detection loop runs a fixed three iterations, each performing only a handful of comparisons. The parity test (i & 1) replaces a modulo operation, offering a marginally faster determination of the current player. Returning a string constructed from a single character (string(1, board[i][0])) avoids creating larger temporary objects.
Overall, the solution operates with minimal memory footprint and constant-time work for each phase, making it well-suited for the constrained 3×3 Tic-Tac-Toe board.
ELI5 - Simplified Explanation
Imagine a wide, empty tic-tac-toe board drawn on a piece of paper. This code acts like a tiny robot that watches two friends, named A and B, take turns writing their letters on the grid.
First, the robot clears off any old marks so the board is completely empty. Then, it looks at a list of every move the friends make. For each move, the robot knows exactly which square the friend chose, and it draws their special letter, either an A or a B, right where it belongs.
Once the moves are finished, the robot looks at the grid to see if anyone won. It checks all the rows, all the columns, and both of the long diagonal lines that cross through the center. If it sees three matching letters in a row, it tells everyone who the winner is. If all the boxes are full and nobody managed to line up three letters, the robot says it is a draw, which is just like a tie. If the board still has empty spots and no one has won yet, the robot tells us that the game is still going on.
Code Quality
Complexity Analysis
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| author | solutions | |||||||||
| www | AlgoMonster | C++ | Python | Java | TS | |||||
| WalkCCC | C++ | Python | Java | |||||||
| leetcode.ca | C++ | Python | Java | Go | TS | |||||
| Progiez | C++ | Python | Java | |||||||
| github | BigEggStudy | C# | ||||||||
| black-shadows | C++ | |||||||||
| charles-wangkai | Java | |||||||||
| DimitrisJim | C | |||||||||
| everthis | JS | |||||||||
| fartem | Ruby | |||||||||
| fsq | C++ | |||||||||
| Garvit244 | Python | |||||||||
| halfrost | Go | |||||||||
| JoshCrozier | JS | |||||||||
| keineahnung2345 | C++ | |||||||||
| lkwq007 | Python | |||||||||
| suxrobGM | C# | |||||||||
| varunu28 | Java | |||||||||
| AlgoMonster | C++, Python, Java, TypeScript | |||||||||
| WalkCCC | C++, Python, Java | |||||||||
| leetcode.ca | C++, Go, Java, Python, TypeScript | |||||||||
| Progiez | C++, Java, Python | |||||||||
| BigEggStudy | C# | |||||||||
| black-shadows | C++, C++ | |||||||||
| charles-wangkai | Java | |||||||||
| DimitrisJim | C | |||||||||
| everthis | JavaScript | |||||||||
| fartem | Ruby | |||||||||
| fsq | C++ | |||||||||
| Garvit244 | Python | |||||||||
| halfrost | Go | |||||||||
| JoshCrozier | JavaScript | |||||||||
| keineahnung2345 | C++ | |||||||||
| lkwq007 | Python | |||||||||
| suxrobGM | C# | |||||||||
| varunu28 | Java |
Videos
Solved On The Same Day
- problem 13: Roman to Integer
- problem 21: Merge Two Sorted Lists
- problem 28: Find the Index of the First Occurrence in a String
- problem 35: Search Insert Position
- problem 58: Length of Last Word
- problem 66: Plus One
- problem 67: Add Binary
- problem 69: Sqrt(x)
- problem 70: Climbing Stairs
- problem 206: Reverse Linked List
- problem 242: Valid Anagram
- problem 278: First Bad Version
- problem 283: Move Zeroes
- problem 367: Valid Perfect Square
- problem 374: Guess Number Higher or Lower
- problem 389: Find the Difference
- problem 441: Arranging Coins
- problem 459: Repeated Substring Pattern
- problem 509: Fibonacci Number
- problem 657: Robot Return to Origin
- problem 682: Baseball Game
- problem 704: Binary Search
- problem 709: To Lower Case
- problem 744: Find Smallest Letter Greater Than Target
- problem 746: Min Cost Climbing Stairs
- problem 860: Lemonade Change
- problem 896: Monotonic Array
- problem 976: Largest Perimeter Triangle
- problem 1137: N-th Tribonacci Number
- problem 1232: Check If It Is a Straight Line
- problem 1351: Count Negative Numbers in a Sorted Matrix
- problem 1491: Average Salary Excluding the Minimum and Maximum Salary
- problem 1502: Can Make Arithmetic Progression From Sequence
- problem 1523: Count Odd Numbers in an Interval Range
- problem 1539: Kth Missing Positive Number
- problem 1572: Matrix Diagonal Sum
- problem 1672: Richest Customer Wealth
- problem 1768: Merge Strings Alternately
- problem 1822: Sign of the Product of an Array
- problem 2: Add Two Numbers
- problem 5: Longest Palindromic Substring
- problem 33: Search in Rotated Sorted Array
- problem 34: Find First and Last Position of Element in Sorted Array
- problem 43: Multiply Strings
- problem 50: Pow(x, n)
- problem 54: Spiral Matrix
- problem 62: Unique Paths
- problem 63: Unique Paths II
- problem 64: Minimum Path Sum
- problem 73: Set Matrix Zeroes
- problem 74: Search a 2D Matrix
- problem 120: Triangle
- problem 139: Word Break
- problem 153: Find Minimum in Rotated Sorted Array
- problem 198: House Robber
- problem 221: Maximal Square
- problem 275: H-Index II
- problem 279: Perfect Squares
- problem 300: Longest Increasing Subsequence
- problem 436: Find Right Interval
- problem 445: Add Two Numbers II
- problem 528: Random Pick with Weight
- problem 540: Single Element in a Sorted Array
- problem 611: Valid Triangle Number
- problem 658: Find K Closest Elements
- problem 852: Peak Index in a Mountain Array
- problem 981: Time Based Key-Value Store
- problem 1041: Robot Bounded In Circle
- problem 1146: Snapshot Array
- problem 2300: Successful Pairs of Spells and Potions
- problem 154: Find Minimum in Rotated Sorted Array II
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality