51.N皇后

:做题思路痕迹

class Solution {

    List<String> temp = new ArrayList<>();
    
    List<List<String>> res = new ArrayList<>();

    // 记录皇后位置
    List<Integer> list = new ArrayList<>();

    public List<List<String>> solveNQueens(int n) {
        backtrace(n, list);
        return res;
    }

    // 维护一个二维数组?记录每个皇后的位置
    // 判断是否合适的函数boolean
    // n*n生成所有的list<String>
    // int[][] nums = new int[n][n];
    // for(int i = 0; i < n; i++){
    //     for(int j = 0; j < n; j++){
    //         nums[i][j]
    //     }
        
    // }

    

    // 用一个集合记录上面的所有层中皇后的位置,在本层不能出现相同的位置
    public void backtrace(int n, List<Integer> list){
        // StringBuilder str = new StringBuilder();
        if(list.size() == n){
            // 这里的list都满足0到n-1一个数仅一次。list中存的数代表列坐标,所以合法判断时就不用判断列,行也不会重复
            if(isVaild(list, n)){
                // 转化成string存到temp,在存到res中
                temp = convert(list, n);
                res.add(new ArrayList(temp));
                temp = new ArrayList<>();
                return;
            }
            // ans.add(new ArrayList(temp));
            return;
        }
        for(int i = 0; i < n; i++){
            // 这里
            if(!list.contains(i)) {
                list.add(i);
            } else {
                continue;
            }
            backtrace(n, list);
            list.remove(list.size() - 1);
            // str.append()
        }
    }

    // 转化
    public List<String> convert(List<Integer> list, int n){
        char[] chs = new char[n];
        for(int i = 0; i < n; i++){
            // 外层for为了遍历list
            for(int j = 0; j < n; j++){
                // 遍历char
                if(j == list.get(i)){
                    chs[j] = 'Q';
                } else{
                    chs[j] = '.';
                }
                
            }
            temp.add(new String(chs));    
        }
        return temp;
    }

    // 
    public boolean isVaild(List<Integer> list, int n){
        //
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                // 正对角线
                if(i != j && i + list.get(j) == j + list.get(i)) return false;
                // i的shang对角线判断
                // if(i != j && i + j == list.get(i) + list.get(j)) return false;
                // i的下对角线判断
                // if(i < j && list.get(i) == list.get(j) + i - j) return false;
                // 反对角线合并
                if(i != j && list.get(i) + i == list.get(j) + j) return false;
                /*
                // i的左下对角线判断
                if(i < j && list.get(i) + i == list.get(j) + j) return false;
                // i的右上对角线判断
                if(i > j && )
                */
            }
        }
        return true;
    }

    // public boolean vaild(int n)

    // 2代表皇后,1代表不能赋值,0可以
    // hanshu:将二维数组的某个点的同行、同列、对角线上的0全变成1
    // public void change(int[][] nums, int row, int col){
    //     // row
    //     for(int i = 0; i < nums.length; i++){
    //         if(nums[row][i] != 2){
    //             nums[row][i] = 1;
    //         }
    //     }
    //     // col
    //     for(int i = 0; i < nums.length; i++){
    //         if(nums[i][col] != 2){
    //             nums[i][col] = 1;
    //         }
    //     }
    //     // 斜线

    // }

}

:通过后,修改,好看点

class Solution {

    List<String> temp = new ArrayList<>();
    
    List<List<String>> res = new ArrayList<>();

    // 记录皇后位置
    List<Integer> list = new ArrayList<>();

    public List<List<String>> solveNQueens(int n) {
        backtrace(n, list);
        return res;
    }
    

    public void backtrace(int n, List<Integer> list){
        // StringBuilder str = new StringBuilder();
        if(list.size() == n){
            // 这里的list都满足0到n-1一个数仅一次。list中存的数代表列坐标,所以合法判断时就不用判断列,行也不会重复
            if(isVaild(list, n)){
                // 转化成string存到temp,在存到res中
                temp = convert(list, n);
                res.add(new ArrayList(temp));
                temp = new ArrayList<>();
                return;
            }
            // ans.add(new ArrayList(temp));
            return;
        }
        for(int i = 0; i < n; i++){
            // 这里
            if(!list.contains(i)) {
                list.add(i);
            } else {
                continue;
            }
            backtrace(n, list);
            list.remove(list.size() - 1);
        }
    }

    // 转化
    public List<String> convert(List<Integer> list, int n){
        char[] chs = new char[n];
        for(int i = 0; i < n; i++){
            // 外层for为了遍历list
            for(int j = 0; j < n; j++){
                // 遍历char
                if(j == list.get(i)){
                    chs[j] = 'Q';
                } else{
                    chs[j] = '.';
                }
                
            }
            temp.add(new String(chs));    
        }
        return temp;
    }

    // 
    public boolean isVaild(List<Integer> list, int n){
        //
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                // 正对角线
                if(i != j && i + list.get(j) == j + list.get(i)) return false;
                // 反对角线
                if(i != j && list.get(i) + i == list.get(j) + j) return false;
            }
        }
        return true;
    }

}

// 我是用List<Integer>,数字型,为了更好地判断合法,但还要将list使用双层for转化成"."和"Q"。如果直接用List<String>,字符型,和一个二维数组判断,就不用“转化”这个开销了。能减小点时间开销?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值