LeetCode 348: Design Tic-Tac-Toe (O(1) Per Move)
LeetCode 348Source: https://leetcode.com/problems/design-tic-tac-toe/
English
Track row, column, diagonal, and anti-diagonal sums. Player 1 adds +1 and player 2 adds -1. If absolute value of any tracked counter reaches n after a move, that player wins. This gives O(1) per move and O(n) memory.
class TicTacToe {
private final int[] rows, cols;
private int diag = 0, anti = 0, n;
public TicTacToe(int n) {
this.n = n;
rows = new int[n];
cols = new int[n];
}
public int move(int row, int col, int player) {
int add = player == 1 ? 1 : -1;
rows[row] += add;
cols[col] += add;
if (row == col) diag += add;
if (row + col == n - 1) anti += add;
if (Math.abs(rows[row]) == n || Math.abs(cols[col]) == n || Math.abs(diag) == n || Math.abs(anti) == n) return player;
return 0;
}
}type TicTacToe struct { rows, cols []int; diag, anti, n int }
func Constructor(n int) TicTacToe { return TicTacToe{rows: make([]int,n), cols: make([]int,n), n:n} }
func (t *TicTacToe) Move(row int, col int, player int) int {
add := -1; if player == 1 { add = 1 }
t.rows[row] += add; t.cols[col] += add
if row == col { t.diag += add }
if row+col == t.n-1 { t.anti += add }
if abs(t.rows[row])==t.n || abs(t.cols[col])==t.n || abs(t.diag)==t.n || abs(t.anti)==t.n { return player }
return 0
}
func abs(x int) int { if x<0 { return -x }; return x }class TicTacToe {
vector rows, cols; int diag=0, anti=0, n;
public:
TicTacToe(int n): rows(n), cols(n), n(n) {}
int move(int row, int col, int player) {
int add = (player==1)?1:-1;
rows[row]+=add; cols[col]+=add;
if(row==col) diag+=add;
if(row+col==n-1) anti+=add;
if(abs(rows[row])==n||abs(cols[col])==n||abs(diag)==n||abs(anti)==n) return player;
return 0;
}
}; class TicTacToe:
def __init__(self, n: int):
self.n=n; self.rows=[0]*n; self.cols=[0]*n; self.diag=0; self.anti=0
def move(self, row: int, col: int, player: int) -> int:
add = 1 if player==1 else -1
self.rows[row] += add; self.cols[col] += add
if row==col: self.diag += add
if row+col==self.n-1: self.anti += add
if abs(self.rows[row])==self.n or abs(self.cols[col])==self.n or abs(self.diag)==self.n or abs(self.anti)==self.n:
return player
return 0var TicTacToe = function(n){ this.n=n; this.rows=Array(n).fill(0); this.cols=Array(n).fill(0); this.diag=0; this.anti=0; };
TicTacToe.prototype.move = function(row,col,player){
const add = player===1?1:-1;
this.rows[row]+=add; this.cols[col]+=add;
if(row===col) this.diag+=add;
if(row+col===this.n-1) this.anti+=add;
if(Math.abs(this.rows[row])===this.n||Math.abs(this.cols[col])===this.n||Math.abs(this.diag)===this.n||Math.abs(this.anti)===this.n) return player;
return 0;
};中文
用行、列、主对角线、副对角线计数器做状态压缩。玩家 1 记 +1,玩家 2 记 -1。每次落子后只检查相关计数绝对值是否等于 n,若是则该玩家获胜。单步 O(1),空间 O(n)。
class TicTacToe {
private final int[] rows, cols;
private int diag = 0, anti = 0, n;
public TicTacToe(int n) { this.n = n; rows = new int[n]; cols = new int[n]; }
public int move(int row, int col, int player) {
int add = player == 1 ? 1 : -1;
rows[row] += add; cols[col] += add;
if (row == col) diag += add;
if (row + col == n - 1) anti += add;
if (Math.abs(rows[row]) == n || Math.abs(cols[col]) == n || Math.abs(diag) == n || Math.abs(anti) == n) return player;
return 0;
}
}type TicTacToe struct { rows, cols []int; diag, anti, n int }
func Constructor(n int) TicTacToe { return TicTacToe{rows: make([]int,n), cols: make([]int,n), n:n} }
func (t *TicTacToe) Move(row int, col int, player int) int {
add := -1; if player == 1 { add = 1 }
t.rows[row] += add; t.cols[col] += add
if row == col { t.diag += add }
if row+col == t.n-1 { t.anti += add }
if abs(t.rows[row])==t.n || abs(t.cols[col])==t.n || abs(t.diag)==t.n || abs(t.anti)==t.n { return player }
return 0
}
func abs(x int) int { if x<0 { return -x }; return x }class TicTacToe {
vector rows, cols; int diag=0, anti=0, n;
public:
TicTacToe(int n): rows(n), cols(n), n(n) {}
int move(int row, int col, int player) {
int add = (player==1)?1:-1;
rows[row]+=add; cols[col]+=add;
if(row==col) diag+=add;
if(row+col==n-1) anti+=add;
if(abs(rows[row])==n||abs(cols[col])==n||abs(diag)==n||abs(anti)==n) return player;
return 0;
}
}; class TicTacToe:
def __init__(self, n: int):
self.n=n; self.rows=[0]*n; self.cols=[0]*n; self.diag=0; self.anti=0
def move(self, row: int, col: int, player: int) -> int:
add = 1 if player==1 else -1
self.rows[row] += add; self.cols[col] += add
if row==col: self.diag += add
if row+col==self.n-1: self.anti += add
if abs(self.rows[row])==self.n or abs(self.cols[col])==self.n or abs(self.diag)==self.n or abs(self.anti)==self.n:
return player
return 0var TicTacToe = function(n){ this.n=n; this.rows=Array(n).fill(0); this.cols=Array(n).fill(0); this.diag=0; this.anti=0; };
TicTacToe.prototype.move = function(row,col,player){
const add = player===1?1:-1;
this.rows[row]+=add; this.cols[col]+=add;
if(row===col) this.diag+=add;
if(row+col===this.n-1) this.anti+=add;
if(Math.abs(this.rows[row])===this.n||Math.abs(this.cols[col])===this.n||Math.abs(this.diag)===this.n||Math.abs(this.anti)===this.n) return player;
return 0;
};
Comments