算法题解:N皇后问题(JAVA代码)

算法题解:N皇后问题(JAVA代码)

n皇后是把n个棋子皇后放在n×n棋盘上,这样就不会有两个皇后互相攻击。

算法题解:N皇后问题(JAVA代码)_第1张图片

例如,下面是4皇后问题的解决方案。

算法题解:N皇后问题(JAVA代码)_第2张图片

算法题解:N皇后问题(JAVA代码)_第3张图片 

设计一个算法,输出在4*4的棋盘上,4皇后问题的解决方案。


 算法分析

回溯算法(Backtracking Algorithm)解决N皇后问题

算法思想是把皇后(Queen)一个接一个地放在不同的列中,从最左边的列开始。当我们把一个皇后放在一列中时,我们会检查是否与已经放置的皇后发生冲突。在当前列中,如果找到没有冲突的行,则将此行和列标记为解决方案的一部分。如果由于冲突而找不到这样的行,那么我们将回溯并返回false。

 

  1. 从最左边的列开始
  2. 如果所有的Queen都已经放置,则返回true
  3. 在当前列中,尝试遍历所有的行进行检查。在每一行的尝试中,按照下面的内容进行判断

3-1)如果Queen可以被安全的放置在这一行,那么标记这个位置 [row,column],得到一个解决方案。

         然后进行递归检查。

            3-2)如果把Queen放置在某个位置 [row, column] 得到解决方案,则返回 true

            3-3)如果放置Queen不会得到解决方案,则取消标记此位置 [row,column](Backtrack,回溯),然后转到步骤(3-1)再继续尝试其他行。

      4. 如果已尝试所有行,但没有任何操作,返回false以触发回溯。


算法设计

package com.bean.algorithm.basic;

public class NQueenProblem {
	
	static int N = 4;
	static int k = 1;

	/* 输出解决方案 */
	static void printSolution(int board[][]) {
		System.out.printf("%d-\n", k++);
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++)
				System.out.printf(" %d ", board[i][j]);
			System.out.printf("\n");
		}
		System.out.printf("\n");
	}


	static boolean isSafe(int board[][], int row, int col) {
		int i, j;

		for (i = 0; i < col; i++) {
			if (board[row][i] == 1) {
				return false;
			}
		}

		for (i = row, j = col; i >= 0 && j >= 0; i--, j--) {
			if (board[i][j] == 1) {
				return false;
			}
		}
	
		for (i = row, j = col; j >= 0 && i < N; i++, j--) {
			if (board[i][j] == 1) {
				return false;
			}
		}
		
		return true;
	}

	/*
	 * 递归算法求解N皇后问题
	 */
	static boolean solveNQUtil(int board[][], int col) {
		/*
		 * 如果所有的皇后都放置到位置,则返回true
		 */
		if (col == N) {
			printSolution(board);
			return true;
		}

		/*
		 * 当前列考虑尝试在每一行放置Queen
		 */
		boolean res = false;
		for (int i = 0; i < N; i++) {
			/*
			 * 检查是否可以将Queen放置在 board[i][col] 位置
			 */
			if (isSafe(board, i, col)) {
				/* 将Queen放置在 board[i][col] 位置 */
				board[i][col] = 1;

				// 如果可以放置,则标记为true
				res = solveNQUtil(board, col + 1) || res;

				/*
				 * 如果将Queen放置在 board[i][col] 位置不能得到一个解决方案,则从 board[i][col] 位置移除Queen
				 */
				board[i][col] = 0; // 回溯 BACKTRACK
			}
		}

		/*
		 * 如果在任何行或者列不能放置Queen,则返回false
		 */
		return res;
	}


	static void solveNQ() {
		int board[][] = new int[N][N];

		if (solveNQUtil(board, 0) == false) {
			System.out.printf("Solution does not exist");
			return;
		}

		return;
	}


	public static void main(String[] args) {
		// 程序入口点
		solveNQ();
	}
}

程序运行结果

1-
 0  0  1  0 
 1  0  0  0 
 0  0  0  1 
 0  1  0  0 

2-
 0  1  0  0 
 0  0  0  1 
 1  0  0  0 
 0  0  1  0 

 

你可能感兴趣的:(算法分析与设计)