leetcode第52题

简介: 可以发现对于同一条副对角线,row + col 的值是相等的。对于同一条主对角线,row - col 的值是相等的。我们同样可以用一个 bool 型数组,来保存当前对角线是否有元素,把它们相加相减的值作为下标。对于 row - col ,由于出现了负数,所以可以加 1 个 n,由 [ - 3, 3 ] 转换为 [ 1 , 7 ] 。

image.png

上一题一样,只不过这次不需要返回所有结果,只需要返回有多少个解就可以。

解法一

我们直接把上道题的 ans 的 size 返回就可以了,此外 currentQueen.size ( ) == n 的时候,也不用去生成一个解了,直接加一个数字占位。

publicinttotalNQueens(intn) {
List<Integer>ans=newArrayList<>();
backtrack(newArrayList<Integer>(), ans, n);
returnans.size();
}
privatevoidbacktrack(List<Integer>currentQueen, List<Integer>ans, intn) {
if (currentQueen.size() ==n) {
ans.add(1);
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) {
intcurrent_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;
}

时间复杂度:

空间复杂度:

解法二

参考这里)。

既然不用返回所有解,那么我们就不需要 currentQueen 来保存当前已加入皇后的位置。只需要一个 bool 型数组,来标记列是否被占有就可以了。

由于没有了 currentQueen,所有不能再用之前 isDiagonalAttack 判断对角线冲突的方法了。我们可以观察下,对角线元素的情况。

image.png

可以发现对于同一条副对角线,row + col 的值是相等的。

对于同一条主对角线,row - col 的值是相等的。

我们同样可以用一个 bool 型数组,来保存当前对角线是否有元素,把它们相加相减的值作为下标。

对于 row - col ,由于出现了负数,所以可以加 1 个 n,由 [ - 3, 3 ] 转换为 [ 1 , 7 ] 。

publicinttotalNQueens(intn) {
List<Integer>ans=newArrayList<>();
boolean[] cols=newboolean[n]; // 列boolean[] d1=newboolean[2*n]; // 主对角线 boolean[] d2=newboolean[2*n]; // 副对角线returnbacktrack(0, cols, d1, d2, n, 0);
}
privateintbacktrack(introw, boolean[] cols, boolean[] d1, boolean[] d2, intn, intcount) { 
if (row==n) {
count++;
    } else {
for (intcol=0; col<n; col++) {
intid1=row-col+n; //主对角线加 nintid2=row+col;
if (cols[col] ||d1[id1] ||d2[id2])
continue;
cols[col] =true;
d1[id1] =true;
d2[id2] =true;
count=backtrack(row+1, cols, d1, d2, n, count);
cols[col] =false;
d1[id1] =false;
d2[id2] =false;
        }
    }
returncount;
}

时间复杂度:

空间复杂度:

和上一题相比,通过三个 bool 型数组来标记是否占有,不存储具体的位置,从而解决了这道题。


相关文章
|
7月前
|
消息中间件 Kubernetes NoSQL
LeetCode 3、28、1351
LeetCode 3、28、1351
|
存储
leetcode:53.最大字序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
53 0
顺手牵羊(LeetCode844.)
好多同学说这是双指针法,但是我认为叫它顺手牵羊法更合适
82 0
LeetCode 389. 找不同
给定两个字符串 s 和 t,它们只包含小写字母。
78 0
LeetCode 354. Russian Doll Envelopes
给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。 请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。
82 0
LeetCode 354. Russian Doll Envelopes
|
算法 Python
LeetCode 386. Lexicographical Numbers
给定一个整数 n, 返回从 1 到 n 的字典顺序。
88 0
LeetCode 386. Lexicographical Numbers
leetcode 283 移动零
leetcode 283 移动零
57 0
leetcode第53题
解法一和解法二的动态规划,只是在定义的时候一个表示以 i 开头的子数组,一个表示以 i 结尾的子数组,却造成了时间复杂度的差异。问题就是解法一中求出了太多的没必要的和,不如解法二直接,只保存最大的和。
leetcode第53题
leetcode第48题
将一个矩阵顺时针旋转 90 度,并且不使用额外的空间。大概属于找规律的题,没有什么一般的思路,观察就可以了。 解法一 可以先转置,然后把每列对称交换交换一下
leetcode第48题