N皇后问题--解法一(递归遍历斜线)

import java.util.*;
import java.math.*;

public class Solution {

    TreeSet<Integer> ready = new TreeSet<Integer>();
    HashSet<Integer> res = new HashSet<Integer>();
    Integer midNum = 0;
    //已经摆放几个
    int leng = 0;
    //多少种摆法
    int count = 0;
    int len = 0;
    boolean found = false;
    HashSet<Integer> readyX = new HashSet<Integer>();
    HashSet<Integer> readyY = new HashSet<Integer>();
    /**
     *
     * @param n int整型 the n
     * @return int整型
     */
    public int Nqueen (int n) {
        len = n;
        recursion();
        return res.size();
    }
    private void recursion() {

        if (leng == len) {
            midNum = 0;
            //ready 元素顺序不同,迭代的直不同,所以要去重的话,只能使用treeset排序
            ready.forEach(x-> midNum = 31*midNum + x);
            //利用hashset去重
            res.add(midNum);
         //  }
            
            return;
        }
        for (int x = 1 ; x <= len; x++ ) {
            for (int y = 1 ; y <= len ; y++) {
                found = false;
                //沿着斜线判断
                find(x, y, 1);
                find(x, y, 2);
                find(x, y, 3);
                find(x, y, 4);
                if (!found && !readyX.contains(x) && !readyY.contains(y)) {
                    leng++;
                    int hashCode = 31 * (31 * 1 + y) + x;
                   // String hashCode = x + "-" + y;
                    ready.add(hashCode);
                    readyX.add(x);
                    readyY.add(y);
                    //进入下一个寻找Q的迭代
                    recursion();
                    //每确定一个Q的位置,回溯
                    //回溯只能保证当前Q进入其他分支,但是其他Q仍然可以在当前分支
                    //而每个Q的位置要考虑的是组合而不是排列
                    ready.remove(hashCode);
                    readyX.remove(x);
                    readyY.remove(y);
                    leng--;
                    //一行只能有一个Q
                    break;
                }
            }
        }


    }
    private void find(int x, int y, int num) {

        if (found) {
            return;
        }
        int hashCode = 31 * (31 * 1 + y) + x;
        //String hashCode = x + "-" + y;
        if (ready.contains(hashCode)) {
            found = true;
            return;
        }
        //斜线
        if (num == 1 && x < len && y < len)
            find(x + 1, y + 1, 1);
        if (num == 2 && x < len && y > 0)
           find(x + 1, y - 1, 2);
        if (num == 3 && x > 0 && y < len)
            find(x - 1, y + 1, 3);
        if (num == 4 && x > 0 && y > 0)
            find(x - 1, y - 1, 4);

    }
}

  n = 9  运行时间 7s

posted @ 2022-10-26 15:22  yanher  阅读(30)  评论(0)    收藏  举报