leetcode第51题

简介: 较经典的回溯问题了,我们需要做的就是先在第一行放一个皇后,然后进入回溯,放下一行皇后的位置,一直走下去,如果已经放的皇后的数目等于 n 了,就加到最后的结果中。然后再回到上一行,变化皇后的位置,然后去找其他的解。期间如果遇到当前行所有的位置都不能放皇后了,就再回到上一行,然后变化皇后的位置。再返回到下一行。说起来可能还费力些,直接看代码吧。

image.png

经典的 N 皇后问题。意思就是摆皇后的位置,每行每列以及对角线只能出现 1 个皇后。输出所有的情况。

解法一 回溯法

比较经典的回溯问题了,我们需要做的就是先在第一行放一个皇后,然后进入回溯,放下一行皇后的位置,一直走下去,如果已经放的皇后的数目等于 n 了,就加到最后的结果中。然后再回到上一行,变化皇后的位置,然后去找其他的解。

期间如果遇到当前行所有的位置都不能放皇后了,就再回到上一行,然后变化皇后的位置。再返回到下一行。

说起来可能还费力些,直接看代码吧。

publicList<List<String>>solveNQueens(intn) {
List<List<String>>ans=newArrayList<>();
backtrack(newArrayList<Integer>(), ans, n);
returnans;
}
privatevoidbacktrack(List<Integer>currentQueen, List<List<String>>ans, intn) {
// 当前皇后的个数是否等于 n 了,等于的话就加到结果中if (currentQueen.size() ==n) {
List<String>temp=newArrayList<>();
for (inti=0; i<n; i++) {
char[] t=newchar[n];
Arrays.fill(t, '.');
t[currentQueen.get(i)] ='Q';
temp.add(newString(t));
        }
ans.add(temp);
return;
    }
//尝试每一列for (intcol=0; col<n; col++) {
//当前列是否冲突if (!currentQueen.contains(col)) {
//判断对角线是否冲突if (isDiagonalAttack(currentQueen, col)) {
continue;
            }
//将当前列的皇后加入currentQueen.add(col);
//去考虑下一行的情况backtrack(currentQueen, ans, n);
//将当前列的皇后移除,去判断下一列//进入这一步就是两种情况,下边的行走不通了回到这里或者就是已经拿到了一个解回到这里currentQueen.remove(currentQueen.size() -1);
        }
    }
}
privatebooleanisDiagonalAttack(List<Integer>currentQueen, inti) {
// TODO Auto-generated method stubintcurrent_row=currentQueen.size();
intcurrent_col=i;
//判断每一行的皇后的情况for (introw=0; row<currentQueen.size(); row++) {
//左上角的对角线和右上角的对角线,差要么相等,要么互为相反数,直接写成了绝对值if (Math.abs(current_row-row) ==Math.abs(current_col-currentQueen.get(row))) {
returntrue;
        }
    }
returnfalse;
}

时间复杂度:

空间复杂度:

上边我们只判断了列冲突和对角线冲突,至于行冲突,由于我们采取一行一行加皇后,所以一行只会有一个皇后,不会产生冲突。

最早接触的一类问题了,学回溯法的话,一般就会以这个为例,所以思路上不会遇到什么困难。

相关文章
|
10月前
|
消息中间件 Kubernetes NoSQL
LeetCode 3、28、1351
LeetCode 3、28、1351
|
存储 Python
LeetCode 66. Plus One
给定表示非负整数的非空数字数组,加上整数的1。 存储数字使得最高有效数字位于列表的开头,并且数组中的每个元素包含单个数字。 您可以假设整数不包含任何前导零,除了数字0本身。
125 0
LeetCode 66. Plus One
leetcode 283 移动零
leetcode 283 移动零
67 0
leetcode第37题
从上到下,从左到右遍历每个空位置。在第一个位置,随便填一个可以填的数字,再在第二个位置填一个可以填的数字,一直执行下去直到最后一个位置。期间如果出现没有数字可以填的话,就回退到上一个位置,换一下数字,再向后进行下去。
103 0
leetcode第37题
leetcode第46题
这是自己开始想到的一个方法,考虑的思路是,先考虑小问题怎么解决,然后再利用小问题去解决大问题。没错,就是递归的思路。比如说, 如果只有 1 个数字 [ 1 ],那么很简单,直接返回 [ [ 1 ] ] 就 OK 了。 如果加了 1 个数字 2, [ 1 2 ] 该怎么办呢?我们只需要在上边的情况里,在 1 的空隙,也就是左边右边插入 2 就够了。变成 [ [ 2 1 ], [ 1 2 ] ]。
leetcode第46题
leetcode第48题
将一个矩阵顺时针旋转 90 度,并且不使用额外的空间。大概属于找规律的题,没有什么一般的思路,观察就可以了。 解法一 可以先转置,然后把每列对称交换交换一下
103 0
leetcode第48题
|
算法
leetcode第40题
会发现出现了很多重复的结果,就是因为没有跳过重复的 1。在求 opt [ 1 ] 的时候就变成了 [ [ 1 ],[ 1 ] ] 这样子,由于后边求的时候都是直接在原来每一个列表里加数字,所有后边都是加了两次了。
leetcode第40题
|
存储 算法
leetcode第43题
个位乘个位,得出一个数,然后个位乘十位,全部乘完以后,就再用十位乘以各个位。然后百位乘以各个位,最后将每次得出的数相加。十位的结果要补 1 个 0 ,百位的结果要补两个 0 。相加的话我们可以直接用之前的大数相加。直接看代码吧。
104 0
leetcode第43题
|
存储 算法
leetcode第49题
时间复杂度:两层 for 循环,再加上比较字符串,如果字符串最长为 K,总的时间复杂度就是 O(n²K)。 空间复杂度:O(NK),用来存储结果。 解法一算是比较通用的解法,不管字符串里边是大写字母,小写字母,数字,都可以用这个算法解决。这道题的话,题目告诉我们字符串中只有小写字母,针对这个限制,我们可以再用一些针对性强的算法。 下边的算法本质是,我们只要把一类的字符串用某一种方法唯一的映射到同一个位置就可以。
204 0
leetcode第49题