力扣-12.1-51

在这里插入图片描述
在这里插入图片描述
方法一:(自己写的)

class Solution {

    public static boolean isCol(int j,int[][] mark,int n) {
		for(int p=0;p<n;p++) {
			if(mark[p][j]==1) {
				return false;
			}
		}
		return true;
	}
	
	public static boolean isAngle(int i,int j,int[][] mark,int n) {
		// 左上角
		int p=i,q=j;
		while((i-1)>=0 && (j-1)>=0) {
			if(mark[i-1][j-1]==1) {
				return false;
			}
			i-=1;
			j-=1;
		}
		
		// 右上角
		i=p;
		j=q;
		while((i-1)>=0 && (j+1)<n) {
			if(mark[i-1][j+1]==1) {
				return false;
			}
			i-=1;
			j+=1;
		}
		
		// 左下角
		i=p;
		j=q;
		while((i+1)<n && (j-1)>=0) {
			if(mark[i+1][j-1]==1) {
				return false;
			}
			i+=1;
			j-=1;
		}
		
		// 右下角
		i=p;
		j=q;
		while((i+1)<n && (j+1)<n) {
			if(mark[i+1][j+1]==1) {
				return false;
			}
			i+=1;
			j+=1;
		}
		
		return true;
	}
	
	public static void backtracking(int i,List<List<String>> res,char[][] board,int[][] mark,int amount,int n) {
		if(amount==n) {
			List<String> perm=new ArrayList<String>();
			for(char[] temp : board) {
				perm.add(new String(temp));
			}
			res.add(perm);
			return;
		}
		int digit=0;
		for(;digit<n;digit++) {
			if(isCol(digit,mark,n) && isAngle(i,digit,mark,n)) {
				board[i][digit]='Q';
				mark[i][digit]=1;
				amount+=1;
				backtracking(i+1,res, board, mark, amount,n);
				board[i][digit]='.';
				mark[i][digit]=0;
				amount-=1;
			}
		}
	}
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> res=new ArrayList<List<String>>();
		char[][] board=new char[n][n];
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				board[i][j]='.';
			}
		}
		int[][] mark=new int[n][n];
		backtracking(0,res,board,mark,0,n);
		return res;
    }
}

方法二:
45度对角线的横坐标和纵坐标的之和相同
135度对角线的横坐标和纵坐标的之差相同

class Solution {
    
	public static void backtracking(int row,List<List<String>> res,boolean[] colUsed,boolean[] diagonals45Used,boolean[] diagonals135Used,int n,char[][] board) {
		if (row == n) {
	        List<String> list = new ArrayList<>();
	        for (char[] chars : board) {
	            list.add(new String(chars));
	        }
	        res.add(list);
	        return;
	    }
		for (int col = 0; col < n; col++) {
	        int diagonals45Idx = row + col; // 45度角的对角线的横纵坐标之和相等
	        int diagonals135Idx = n - 1 + (row - col); // 135度角的对角线的横纵坐标之差相等
	        if (colUsed[col] || diagonals45Used[diagonals45Idx] || diagonals135Used[diagonals135Idx]) {
	            continue;
	        }
	        board[row][col] = 'Q';
	        colUsed[col] = diagonals45Used[diagonals45Idx] = diagonals135Used[diagonals135Idx] = true;
	        backtracking(row + 1,res,colUsed,diagonals45Used,diagonals135Used,n,board);
	        colUsed[col] = diagonals45Used[diagonals45Idx] = diagonals135Used[diagonals135Idx] = false;
	        board[row][col] = '.';
	    }
	}

    public List<List<String>> solveNQueens(int n) {
        List<List<String>> res=new ArrayList<List<String>>();
		char[][] board=new char[n][n];
	    for (int i = 0; i < n; i++) {
	        Arrays.fill(board[i], '.');
	    }
	    boolean[] colUsed = new boolean[n];
	    boolean[] diagonals45Used = new boolean[2 * n - 1];
	    boolean[] diagonals135Used = new boolean[2 * n - 1];
	    backtracking(0,res,colUsed,diagonals45Used,diagonals135Used,n,board);
		return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值