lintcode 中等题:N Queens N皇后问题

题目:

N皇后问题

n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击。《不同行,不同列,不同对角线》

给定一个整数n,返回所有不同的n皇后问题的解决方案。

每个解决方案包含一个明确的n皇后放置布局,其中“Q”和“.”分别表示一个女王和一个空位置。

样例

对于4皇后问题存在两种解决的方案:

[

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

"...Q",

"Q...",

"..Q."],

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

"Q...",

"...Q",

".Q.."]

]

挑战

你能否不使用递归完成?

解题:

题意:在n*n的棋盘上,保证n个皇后,不同行,不同列,不同对角线,这样的组合方式有多少种,并求出所以的组合方式。

在网上看到下面的思路:

在n*n的矩阵中,n个皇后分别在0-n-1行,也就是说,第i个皇后在第i行是固定的,但是在第多少列?用到回溯法进行解决。

对第i个皇后,依次考虑0 - n-1列的位置是否合法,若在第k列的位置合法,则再考虑下一个皇后的位置。

当i==n的时候并且起位置合法,则保存路径上的各个皇后位置。

如何判断其位置是合法的?

1.暴力,定义矩阵,对新来的点看是否有和它在相同的行,列,对角线

2.定义一个保存所在列的矩阵colVals,其下标就是所在的行,colVals[i]的值就是所在的列值。

显然 不会相同了,只需再考虑列,对角线<正对角线,负对角线>

列值相同:colVals[i] = colVals[row]  ->也就是在相同的列

对角线的时候,可以发现这样的规律:|row - i| = |colVals[row] - colVals[i]| 这里要考虑绝对值,有两种情况的。

其他情况都是合法的。

参考链接
Java程序:

class Solution {
    /**
     * Get all distinct N-Queen solutions
     * @param n: The number of queens
     * @return: All distinct solutions
     * For example, A string ‘...Q‘ shows a queen on forth position
     */
    ArrayList<ArrayList<String>> solveNQueens(int n) {
        // write your code here
        ArrayList<String> path = new ArrayList<String>();
        ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>();
        if( n<0 )
            return result;
        int cols[] = new int[n];
        DFS_helper(n,result,0,cols);
        return result;

    }
    public void DFS_helper(int nQueens,ArrayList<ArrayList<String>> result,int row,int[] cols){
        if(row == nQueens ){
            ArrayList<String> path = new ArrayList<String>();
            for(int i = 0;i<nQueens ;i++){
                String s = "";
                for(int j = 0;j< nQueens ;j++){
                    if(j == cols[i])
                        s = s + "Q";
                    else
                        s = s + ".";
                }
                path.add(s);

            }
            result.add(path);
        }else{
            for(int i = 0;i<nQueens ;i++){
                cols[row] = i;
                if(isValid(row,cols))
                    DFS_helper(nQueens,result,row + 1 ,cols);
            }
        }
    }
    public boolean isValid(int row ,int[] cols){
        for(int i=0;i<row;i++){
            if(cols[row] == cols[i] || Math.abs(cols[row] - cols[i]) == row - i)
            return false;
        }
        return true;
    }
};

总耗时: 1397 ms

"这类型问题统称为递归回溯问题,也可以叫做对决策树的深度优先搜索(dfs)"

竟然也叫深度优先搜索。。。

Python程序:

时间: 2024-10-05 04:54:58

lintcode 中等题:N Queens N皇后问题的相关文章

lintcode 中等题:N Queens II N皇后问题 II

题目: N皇后问题 II 根据n皇后问题,现在返回n皇后不同的解决方案的数量而不是具体的放置布局. 样例 比如n=4,存在2种解决方案 解题: 和上一题差不多,这里只是求数量,这个题目定义全局变量,递归的时候才能保存结果,参考程序 java程序: class Solution { /** * Calculate the total number of distinct N-Queen solutions. * @param n: The number of queens. * @return:

lintcode 中等题:next permutation下一个排列

题目 下一个排列 给定一个整数数组来表示排列,找出其之后的一个排列. 样例 给出排列[1,3,2,3],其下一个排列是[1,3,3,2] 给出排列[4,3,2,1],其下一个排列是[1,2,3,4] 注意 排列中可能包含重复的整数 解题 和上一题求上一个排列应该很类似 1.对这个数,先从右到左找到递增序列的前一个位置,peakInd 2.若peakInd = -1 这个数直接逆序就是答案了 3.peakInd>= 0 peakInd这个位置的所,和 peakInd 到nums.size() -1

lintcode 中等题:maximum subarray difference 最大子数组差

题目 最大子数组差 给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大. 返回这个最大的差值. 样例 给出数组[1, 2, -3, 1],返回 6 注意 子数组最少包含一个数 挑战 时间复杂度为O(n),空间复杂度为O(n) 解题 刚做了数组中两个子数组和的最大值,这一题是求差,感觉上题的求解思想应该是可以用的 A B 分别是两个子数组的和,则: 所以 当A>B 的时候A越大越好 B越小越好 当A<B 的时候B越大越好 A越小越好

lintcode 中等题:continuous subarray sum 联系子数组之和

题目 连续子数组求和 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.(如果两个相同的答案,请返回其中任意一个) 样例 给定 [-3, 1, 3, -3, 4], 返回[1,4]. 解题 法一:直接暴力,时间复杂度O(N2),时间超时 public class Solution { /** * @param A an integer array * @return A list of integers includes the i

lintcode 中等题:maximum subarray最大子数组II

题目 最大子数组 II 给定一个整数数组,找出两个不重叠子数组使得它们的和最大. 每个子数组的数字在数组中的位置应该是连续的. 返回最大的和. 您在真实的面试中是否遇到过这个题? Yes 样例 给出数组[1, 3, -1, 2, -1, 2],这两个子数组分别为[1, 3]和[2, -1, 2]或者[1, 3, -1, 2]和[2],它们的最大和都是7 注意 子数组最少包含一个数 挑战 要求时间复杂度为O(n) 解题 最大子数组I 这个题目是求一个数组中一个最大子数组的和,而本题目是求数组中的前

lintcode 中等题: Implement Trie

题目 Implement Trie Implement a trie with insert, search, and startsWith methods. 样例 注意 You may assume that all inputs are consist of lowercase letters a-z. 解题 Trie,字典树,又称单词查找树.前缀树,是一种哈希树的变种.应用于字符串的统计与排序,经常被搜索引擎系统用于文本词频统计. 性质: 1.根节点不包含字符,除根节点外的每一个节点都只包

lintcode 中等题: 3 Sum II 三数之和II

题目 三数之和 II 给一个包含n个整数的数组S, 找到和与给定整数target最接近的三元组,返回这三个数的和. 样例 例如S = [-1, 2, 1, -4] and target = 1.  和最接近1的三元组是 -1 + 2 + 1 = 2. 注意 只需要返回三元组之和,无需返回三元组本身 解题 和上一题差不多,程序也只是稍微修改了 public class Solution { /** * @param numbers: Give an array numbers of n integ

lintcode 中等题:sort letters by case字符大小写排序

题目 字符大小写排序 给定一个只包含字母的字符串,按照先小写字母后大写字母的顺序进行排序. 您在真实的面试中是否遇到过这个题? Yes 样例 给出"abAcD",一个可能的答案为"acbAD" 注意 小写字母或者大写字母他们之间不一定要保持在原始字符串中的相对位置. 挑战 在原地扫描一遍完成 解题 这个题目很简单,前面刚做一个把大于某个数之和的排在后面,快速排序的思想 public class Solution { /** *@param chars: The le

lintcode 中等题:binary tree level order traversal ii 二叉树的层次遍历II

题目 二叉树的层次遍历 II 给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历) 样例 给出一棵二叉树 {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 按照从下往上的层次遍历为: [ [15,7], [9,20], [3] ] 解题 和上一题的答案反过来 直接每次在list中第一个位置加入当前层结点 /** * Definition of TreeNode: * public class TreeNode { *