2021-12-9每日一题
给你一个字符串数组 board
表示井字游戏的棋盘。当且仅当在井字游戏过程中,棋盘有可能达到 board
所显示的状态时,才返回 true
。
井字游戏的棋盘是一个 3 x 3
数组,由字符 ' '
,'X'
和 'O'
组成。字符 ' '
代表一个空位。
以下是井字游戏的规则:
- 玩家轮流将字符放入空位(
' '
)中。 - 玩家 1 总是放字符
'X'
,而玩家 2 总是放字符'O'
。 'X'
和'O'
只允许放置在空位中,不允许对已放有字符的位置进行填充。- 当有 3 个相同(且非空)的字符填充任何行、列或对角线时,游戏结束。
- 当所有位置非空时,也算为游戏结束。
- 如果游戏结束,玩家不允许再放置字符
考虑到广度优先搜索的熟练度,以及JAVA队列运用的较少,所以没有思考太多因素,写了BFS版本。
1 import java.util.ArrayDeque; 2 import java.util.Arrays; 3 import java.util.Deque; 4 5 public class ValidTicTacToe { 6 public boolean validTicTacToe(String[] board) { 7 Deque<String[]> deque = new ArrayDeque<>(); 8 String[] start={" "," "," "}; 9 deque.add(start); 10 int count=Count(board); 11 int countX=0,countO=0; 12 for (String s : board) { 13 for (int i = 0; i < s.length(); i++) { 14 if (s.charAt(i)=='X'){ 15 countX++; 16 }else if (s.charAt(i)=='O'){ 17 countO++; 18 } 19 } 20 } 21 if (count==0){ 22 return true; 23 }else if (countX<countO){ 24 return false; 25 }else if (isValid(board)){ 26 if (countX!=countO+1&&countX!=countO){ 27 return false; 28 } 29 } 30 while(Count(deque.peek())<count) { 31 String[] poll = deque.poll(); 32 if (!isValid(poll)){ 33 continue; 34 } 35 String fill=check(poll); 36 for (int j = 0; j < poll.length; j++) { 37 for (int k = 0; k < poll[0].length();k++) { 38 if (poll[j].charAt(k)==' '){ 39 String[] clone = poll.clone(); 40 StringBuilder sb= new StringBuilder(clone[j]); 41 sb.replace(k,k+1,fill); 42 clone[j]=sb.toString(); 43 deque.add(clone); 44 if (Count(clone)==count){ 45 if (Arrays.equals(clone, board)){ 46 return true; 47 } 48 } 49 } 50 } 51 } 52 } 53 return false; 54 } 55 56 public static boolean isValid(String[] a){ 57 for (int i = 0; i < 3; i++) { 58 if (a[i].equals("OOO")||a[i].equals("XXX")){ 59 return false; 60 } 61 } 62 for (int i = 0; i < 3; i++) { 63 if (a[0].charAt(i)!=' '&&a[0].charAt(i)==a[1].charAt(i)&&a[1].charAt(i)==a[2].charAt(i)){ 64 return false; 65 } 66 } 67 if (a[0].charAt(0)!=' '&&a[0].charAt(0)==a[1].charAt(1)&&a[1].charAt(1)==a[2].charAt(2)){ 68 return false; 69 }else if (a[0].charAt(2)!=' '&&a[0].charAt(2)==a[1].charAt(1)&&a[1].charAt(1)==a[2].charAt(0)){ 70 return false; 71 } 72 return true; 73 } 74 75 public String check(String[] a){ 76 int countX=0,countO=0; 77 for (String s : a) { 78 for (int i = 0; i < s.length(); i++) { 79 if (s.charAt(i)=='X'){ 80 countX++; 81 }else if (s.charAt(i)=='O'){ 82 countO++; 83 } 84 } 85 } 86 return countO<countX?"O":"X"; 87 } 88 public int Count(String[] a){ 89 int count=0; 90 for (String s : a) { 91 for (int j = 0; j < s.length(); j++) { 92 if (s.charAt(j) != ' ') { 93 count++; 94 } 95 } 96 } 97 return count; 98 } 99 public static void main(String[] args) { 100 String[] a={"OXX","XOX","OXO"}; 101 System.out.println(new ValidTicTacToe().validTicTacToe(a)); 102 } 103 }
结果超时,优化了一部分,还是超时。后来发现只要分类讨论就可以了,BFS权当练习。