LeetCode-找出井字棋的获胜者
我的解答
- 先分组
- 然后再判断每组是否存在成功连线的情况
public class Main {
public static void main(String[] args) throws Exception {
int[][] moves=new int[][]{{0,0}, {1,1},{2,0},{1,0},{1,2},{2,1},{0,1},{0,2},{2,2}};
System.out.println(tictactoe(moves));
}
public static String tictactoe(int[][] moves) {
List<int[]> listA=new ArrayList<>();
List<int[]> listB=new ArrayList<>();
for(int i=0;i<moves.length;i++){
if(i%2==0){
listA.add(moves[i]);
}
else{
listB.add(moves[i]);
}
}
if(hasThree(listA)){
return "A";
}
if(hasThree(listB)){
return "B";
}
if(moves.length<9){
return "Pending";
}
return "Draw";
}
private static boolean isEqual(int[] old,int[] _new){
return Arrays.equals(old,_new);
}
private static boolean hasThree(List<int[]> moves){
int _one=0,_two=0,_three=0,_four=0,_five=0,_six=0,_seven=0,_eight=0;
for(int i=0;i<moves.size();i++){
if(Arrays.equals(moves.get(i), new int[]{0, 0}) ||Arrays.equals(moves.get(i),new int[]{0,1})||Arrays.equals(moves.get(i),new int[]{0,2})){
_one++;
}
if(Arrays.equals(moves.get(i),new int[]{1,0})||Arrays.equals(moves.get(i),new int[]{1,1})||Arrays.equals(moves.get(i),new int[]{1,2})){
_two++;
}
if(Arrays.equals(moves.get(i),new int[]{2,0})||Arrays.equals(moves.get(i),new int[]{2,1})||Arrays.equals(moves.get(i),new int[]{2,2})){
_three++;
}
if(Arrays.equals(moves.get(i),new int[]{0,0})||Arrays.equals(moves.get(i),new int[]{1,0})||Arrays.equals(moves.get(i),new int[]{2,0})){
_four++;
}
if(Arrays.equals(moves.get(i),new int[]{0,1})||Arrays.equals(moves.get(i),new int[]{1,1})||Arrays.equals(moves.get(i),new int[]{2,1})){
_five++;
}
if(Arrays.equals(moves.get(i),new int[]{0,2})||Arrays.equals(moves.get(i),new int[]{1,2})||Arrays.equals(moves.get(i),new int[]{2,2})){
_six++;
}
if(Arrays.equals(moves.get(i),new int[]{0,0})||Arrays.equals(moves.get(i),new int[]{1,1})||Arrays.equals(moves.get(i),new int[]{2,2})){
_seven++;
}
if(Arrays.equals(moves.get(i),new int[]{0,2})||Arrays.equals(moves.get(i),new int[]{1,1})||Arrays.equals(moves.get(i),new int[]{2,0})){
_eight++;
}
}
return _one>2||_two>2||_three>2||_four>2||_five>2||_six>2||_seven>2||_eight>2;
}
}
AI的解答
import java.util.*;
public class Main {
// 预定义所有胜利路径(8种可能)
private static final int[][][] WIN_LINES = {
{{0,0}, {0,1}, {0,2}}, // 第一行
{{1,0}, {1,1}, {1,2}}, // 第二行
{{2,0}, {2,1}, {2,2}}, // 第三行
{{0,0}, {1,0}, {2,0}}, // 第一列
{{0,1}, {1,1}, {2,1}}, // 第二列
{{0,2}, {1,2}, {2,2}}, // 第三列
{{0,0}, {1,1}, {2,2}}, // 主对角线
{{0,2}, {1,1}, {2,0}} // 副对角线
};
public static void main(String[] args) {
int[][] moves = {{0,0}, {1,1}, {2,0}, {1,0}, {1,2}, {2,1}, {0,1}, {0,2}, {2,2}};
System.out.println(tictactoe(moves));
}
public static String tictactoe(int[][] moves) {
// 使用Set存储坐标提高查找效率
Set<String> setA = new HashSet<>();
Set<String> setB = new HashSet<>();
for (int i = 0; i < moves.length; i++) {
String pos = moves[i][0] + "," + moves[i][1];
if (i % 2 == 0) setA.add(pos);
else setB.add(pos);
}
if (checkWin(setA)) return "A";
if (checkWin(setB)) return "B";
return moves.length == 9 ? "Draw" : "Pending";
}
private static boolean checkWin(Set<String> moves) {
// 检查所有胜利路径
for (int[][] line : WIN_LINES) {
int count = 0;
for (int[] pos : line) {
if (moves.contains(pos[0] + "," + pos[1])) {
count++;
}
}
if (count == 3) return true; // 找到完整胜利路径
}
return false;
}
}
思考
AI的解答和官方解答思路一致,它们的优点有:
1. 使用预定义的WIN_LINES常量清晰表示8种胜利路径
2. 用HashSet替代ArrayList存储落子位置,将查找复杂度从O(n)降至O(1)
3. 坐标存储为字符串(如"0,0")简化比较操作
4. 避免在每次胜利检查时创建新数组对象(原代码new int[]{0,0})

浙公网安备 33010602011771号