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;
}

时间复杂度:

空间复杂度:

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

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

相关文章
|
6月前
LeetCode
LeetCode
40 0
|
6月前
|
算法
leetcode:389. 找不同
leetcode:389. 找不同
29 0
|
6月前
|
Java
leetcode-474:一和零
leetcode-474:一和零
41 0
LeetCode 389. 找不同
给定两个字符串 s 和 t,它们只包含小写字母。
78 0
leetcode 283 移动零
leetcode 283 移动零
57 0
|
算法
LeetCode——944. 删列造序
LeetCode——944. 删列造序
110 0
leetcode第53题
解法一和解法二的动态规划,只是在定义的时候一个表示以 i 开头的子数组,一个表示以 i 结尾的子数组,却造成了时间复杂度的差异。问题就是解法一中求出了太多的没必要的和,不如解法二直接,只保存最大的和。
leetcode第53题
|
算法
leetcode第45题
时间复杂度:O(n)。 空间复杂度:O(1)。 这里要注意一个细节,就是 for 循环中,i < nums.length - 1,少了末尾。因为开始的时候边界是第 0 个位置,steps 已经加 1 了。如下图,如果最后一步刚好跳到了末尾,此时 steps 其实不用加 1 了。如果是 i < nums.length,i 遍历到最后的时候,会进入 if 语句中,steps 会多加 1 。
107 0
leetcode第45题
|
存储
leetcode第56题
常规的思想,将大问题化解成小问题去解决。 假设给了一个大小为 n 的列表,然后我们假设 n - 1 个元素的列表已经完成了全部合并,我们现在要解决的就是剩下的 1 个,怎么加到已经合并完的 n -1 个元素中。 这样的话分下边几种情况, 我们把每个范围叫做一个节点,节点包括左端点和右端点。 1. 如下图,新加入的节点左端点和右端点,分别在两个节点之间。这样,我们只要删除
104 0
leetcode第56题
leetcode第28题
返回一个字符串 needle 在另一个字符串 haystack 中开始的位置,如果不存在就返回 -1 ,如果 needle 长度是 0 ,就返回 0 。 就是一一比较就好,看下代码吧。
leetcode第28题