[LeetCode 51&52] N-Queens I & II (N皇后问题)

题目链接:n-queens

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 *
		The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

		Given an integer n, return all distinct solutions to the n-queens puzzle.

		Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.

		For example,
		There exist two distinct solutions to the 4-queens puzzle:

		[
		 [".Q..",  // Solution 1
		  "...Q",
		  "Q...",
		  "..Q."],

		 ["..Q.",  // Solution 2
		  "Q...",
		  "...Q",
		  ".Q.."]
		]
 *
 */

public class NQueens {

//	9 / 9 test cases passed.
//	Status: Accepted
//	Runtime: 217 ms
//	Submitted: 0 minutes ago
	//回溯法
	//时间复杂度O(n!) 空间复杂度O(n)
	public int[] columns;		//存储已放置的皇后占据的列, 		0 未占, 1已占
	public int[] main_diag;		//存储已放置的皇后占据的主对角线, 0 未占, 1已占
	public int[] anti_diag;		//存储已放置的皇后占据的副对角线, 0 未占, 1已占
	public String[] st_str;
	public List<String[]> nQueens = new ArrayList<String[]>();

	public void init(int n) {
        columns = new int[n];
        main_diag = new int[2 * n];
        anti_diag = new int[2 * n];
        Arrays.fill(columns, 0);
        Arrays.fill(main_diag, 0);
        Arrays.fill(anti_diag, 0);
    	createString(n);
	}

	public void createString (int n) {
		st_str = new String[n];
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < n; i++) {
			sb.append(".");
		}
		for (int i = 0; i < n; i++) {
			sb.replace(i, i + 1, "Q");
			st_str[i] = sb.toString();
			sb.replace(i, i + 1, ".");
		}
	}	

    public List<String[]> solveNQueens(int n) {
    	//初始化各状态变量
    	init(n);

    	int[] C = new int[n];
    	Arrays.fill(C, 0);

    	dfs(C, 0);
    	return nQueens;
    }

    public void dfs(int[] C, int row) {
    	int N = C.length;
    	//表示找到一个可行解
    	if(row == N) {
    		String[] nQueen = new String[N];
    		for (int i = 0; i < N; i++) {
				nQueen[i] = st_str[C[i]];
			}
    		nQueens.add(nQueen);
    		return;
    	}

    	for (int i = 0; i < N; i++) {

    		//如果不合法,这跳过当前循环
    		if(!(columns[i] == 0
				&& main_diag[i + row] == 0
				&& anti_diag[N - i + row] == 0)) continue;

    		//执行
			C[row] = i;
			columns[i] = 1;
			main_diag[i + row] = 1;
			anti_diag[N - i + row] = 1;

			dfs(C, row + 1);

			//撤销
			C[row] = 0;
			columns[i] = 0;
			main_diag[i + row] = 0;
			anti_diag[N - i + row] = 0;
		}
    }

	public static void main(String[] args) {
		NQueens queens = new NQueens();
		List<String[]> result = queens.solveNQueens(8);
		System.out.println(result.size());
//		for (int i = 0; i < result.size(); i++) {
//			for (int j = 0; j < result.get(i).length; j++) {
//				System.out.println(result.get(i)[j]);
//			}
//			System.out.println();
//		}
	}

}

题目链接:n-queens-ii

import java.util.Arrays;

/**
 *
	Follow up for N-Queens problem.

	Now, instead outputting board configurations, return the total number of distinct solutions.
 *
 */

public class NQueensII {

//	9 / 9 test cases passed.
//	Status: Accepted
//	Runtime: 231 ms
//	Submitted: 0 minutes ago

	//回溯法
	//时间复杂度O(n!) 空间复杂度O(n)
	public int[] columns;		//存储已放置的皇后占据的列, 		0 未占, 1已占
	public int[] main_diag;		//存储已放置的皇后占据的主对角线, 0 未占, 1已占
	public int[] anti_diag;		//存储已放置的皇后占据的副对角线, 0 未占, 1已占
	public int total;

	public void init(int n) {
        columns = new int[n];
        main_diag = new int[2 * n];
        anti_diag = new int[2 * n];
        Arrays.fill(columns, 0);
        Arrays.fill(main_diag, 0);
        Arrays.fill(anti_diag, 0);

        total = 0;				//计数
	}

    public int totalNQueens(int n) {
    	//初始化各状态变量
    	init(n);

    	int[] C = new int[n];
    	Arrays.fill(C, 0);

    	dfs(C, 0);
    	return total;
    }

    public void dfs(int[] C, int row) {
    	int N = C.length;
    	//表示找到一个可行解
    	if(row == N) {
    		total ++;
    		return;
    	}

    	for (int i = 0; i < N; i++) {

    		//如果不合法,这跳过当前循环
    		if(!(columns[i] == 0
				&& main_diag[i + row] == 0
				&& anti_diag[N - i + row] == 0)) continue;

    		//执行
			C[row] = i;
			columns[i] = 1;
			main_diag[i + row] = 1;
			anti_diag[N - i + row] = 1;

			dfs(C, row + 1);

			//撤销
			C[row] = 0;
			columns[i] = 0;
			main_diag[i + row] = 0;
			anti_diag[N - i + row] = 0;
		}
    }

	public static void main(String[] args) {
		NQueensII queens = new NQueensII();

		for (int i = 0; i < 16; i++) {
			System.out.println(i + "- 皇后有 " + queens.totalNQueens(i) + " 种解法");
		}
	}
}

//output
//0- 皇后有 1 种解法
//1- 皇后有 1 种解法
//2- 皇后有 0 种解法
//3- 皇后有 0 种解法
//4- 皇后有 2 种解法
//5- 皇后有 10 种解法
//6- 皇后有 4 种解法
//7- 皇后有 40 种解法
//8- 皇后有 92 种解法
//9- 皇后有 352 种解法
//10- 皇后有 724 种解法
//11- 皇后有 2680 种解法
//12- 皇后有 14200 种解法
//13- 皇后有 73712 种解法
//14- 皇后有 365596 种解法
//15- 皇后有 2279184 种解法
时间: 2024-12-18 02:54:19

[LeetCode 51&52] N-Queens I & II (N皇后问题)的相关文章

[leetcode]Remove Duplicates from Sorted List II @ Python

原题地址:https://oj.leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ 题意: Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example,Given 1->2->3->3->4-&g

[Leetcode][JAVA] Pascal&#39;s Triangle I, II

Pascal's Triangle: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,Return [ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ] 已知行数生成帕斯卡三角.实际上只要有第i层,那么就能生成第i+1层.每次新生成的层加入最终集合中即可. 1 public List<List<Integer&g

[LeetCode] Remove Duplicates from Sorted Array II [27]

题目 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For example, Given sorted array A = [1,1,1,2,2,3], Your function should return length = 5, and A is now [1,1,2,2,3]. 原题链接(点我) 解题思路 移除数组中重复次数超过2次以上出现的数,但是可以允许重复2次

LeetCode: Remove Duplicates from Sorted List II [083]

[题目] Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example, Given 1->2->3->3->4->4->5, return 1->2->5. Given 1->1->1->2->3, return 2-

[leetcode]Binary Tree Level Order Traversal II @ Python

原题地址:http://oj.leetcode.com/problems/binary-tree-level-order-traversal-ii/ 题意: Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). For example:Given binary

[leetcode]Search in Rotated Sorted Array II @ Python

原题地址:https://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/ 题意: Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a function to determine if

[LeetCode] Search in Rotated Sorted Array II [36]

题目 Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a function to determine if a given target is in the array. 原题链接(点我) 解题思路 这题和Search in Rotated Sorted

LeetCode: Remove Duplicates from Sorted Array II [080]

[题目] Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For example, Given sorted array A = [1,1,1,2,2,3], Your function should return length = 5, and A is now [1,1,2,2,3]. [题意] 给定一个有序数组,给数组去重,和Remove Duplicates fro

leetcode第一刷_Linked List Cycle II

这道题稍微有点意思,知道答案发现,呀,这么简单就能做啊.我一开始想的是,相遇之后用另一个指针怎么走,然后满足什么关系之后能推出来,其实不用这么麻烦.是很简单的数学关系,我画个图说一下. S1代表的是链表进入环之前的长度,a代表当两个指针相遇时,走一步的指针在环里走的长度,S2代表的是环的周长,那么根据条件,相遇时,走两步的指针走的距离是走一步的两倍,我们得到公式: (S1+a)*2 = S1+S2+a 化简一下得到 S1 = S2-a 即,环中剩下的长度刚好等于进入链表之前的长度.于是解法是:当