|
@@ -0,0 +1,82 @@
|
|
|
+use std::collections::HashSet;
|
|
|
+
|
|
|
+struct Solution;
|
|
|
+
|
|
|
+impl Solution {
|
|
|
+ pub fn solve(board: &mut Vec<Vec<char>>) {
|
|
|
+ let rows = board.len();
|
|
|
+ let cols = board[0].len();
|
|
|
+ let mut visited = vec![vec![false; cols]; rows];
|
|
|
+ for i in 0..rows {
|
|
|
+ for j in 0..cols {
|
|
|
+ if board[i][j] == 'X' || visited[i][j] { continue }
|
|
|
+ let mut connected = HashSet::new();
|
|
|
+ let mut res = true;
|
|
|
+ Solution::helper(board, rows, cols, &mut visited, (i, j), &mut res, &mut connected);
|
|
|
+ if res {
|
|
|
+ // println!("connected: {:?}", connected);
|
|
|
+ for (ii, jj) in connected.into_iter() {
|
|
|
+ board[ii][jj] = 'X';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ fn helper(board: &mut Vec<Vec<char>>, rows: usize, cols: usize, visited: &mut Vec<Vec<bool>>, cur: (usize, usize), res: &mut bool, connected: &mut HashSet<(usize, usize)> ) {
|
|
|
+ let (ii, jj) = cur;
|
|
|
+ visited[ii][jj] = true;
|
|
|
+ if board[ii][jj] == 'X' {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if ii == rows -1 || jj == cols - 1 || ii == 0 || jj == 0{
|
|
|
+ *res = false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ connected.insert((ii, jj));
|
|
|
+ let i = ii as i32;
|
|
|
+ let j = jj as i32;
|
|
|
+ let candidates = vec![(i, j-1), (i, j+1), (i-1, j), (i+1, j)];
|
|
|
+ let candidates = candidates.into_iter().filter(|(i, j) | *i >= 0 && *j >= 0 && *i < rows as i32 && *j < cols as i32).map(|(i, j)| (i as usize, j as usize)).collect::<Vec<(usize, usize)>>();
|
|
|
+
|
|
|
+ for (i, j) in candidates {
|
|
|
+ if visited[i][j] {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Solution::helper(board, rows, cols, visited, (i, j), res, connected);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(test)]
|
|
|
+mod tests {
|
|
|
+ use super::*;
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn test_solve() {
|
|
|
+ let mut board = vec![vec!['X','X','X','X'],vec!['X','O','O','X'],vec!['X','X','O','X'],vec!['X','O','X','X']];
|
|
|
+ Solution::solve(&mut board);
|
|
|
+ let expected = vec![vec!['X','X','X','X'],vec!['X','X','X','X'],vec!['X','X','X','X'],vec!['X','O','X','X']];
|
|
|
+ assert_eq!(board, expected);
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn test_solve1() {
|
|
|
+ let mut board = vec![vec!['O','X','O','O','O','O','O','O','O'],vec!['O','O','O','X','O','O','O','O','X'],vec!['O','X','O','X','O','O','O','O','X'],vec!['O','O','O','O','X','O','O','O','O'],vec!['X','O','O','O','O','O','O','O','X'],vec!['X','X','O','O','X','O','X','O','X'],vec!['O','O','O','X','O','O','O','O','O'],vec!['O','O','O','X','O','O','O','O','O'],vec!['O','O','O','O','O','X','X','O','O']];
|
|
|
+ Solution::solve(&mut board);
|
|
|
+ let expected = vec![vec!['O','X','O','O','O','O','O','O','O'],vec!['O','O','O','X','O','O','O','O','X'],vec!['O','X','O','X','O','O','O','O','X'],vec!['O','O','O','O','X','O','O','O','O'],vec!['X','O','O','O','O','O','O','O','X'],vec!['X','X','O','O','X','O','X','O','X'],vec!['O','O','O','X','O','O','O','O','O'],vec!['O','O','O','X','O','O','O','O','O'],vec!['O','O','O','O','O','X','X','O','O']];
|
|
|
+ assert_eq!(board, expected);
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|