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 型数组来标记是否占有,不存储具体的位置,从而解决了这道题。


相关文章
|
4月前
LeetCode
LeetCode
32 0
|
4月前
|
算法
leetcode:389. 找不同
leetcode:389. 找不同
21 0
顺手牵羊(LeetCode844.)
好多同学说这是双指针法,但是我认为叫它顺手牵羊法更合适
67 0
|
索引
|
存储 Python
LeetCode 66. Plus One
给定表示非负整数的非空数字数组,加上整数的1。 存储数字使得最高有效数字位于列表的开头,并且数组中的每个元素包含单个数字。 您可以假设整数不包含任何前导零,除了数字0本身。
82 0
LeetCode 66. Plus One
leetcode第38题
难在了题目是什么意思呢? 初始值第一行是 1。 第二行读第一行,1 个 1,去掉个字,所以第二行就是 11。 第三行读第二行,2 个 1,去掉个字,所以第三行就是 21。 第四行读第三行,1 个 2,1 个 1,去掉所有个字,所以第四行就是 1211。 第五行读第四行,1 个 1,1 个 2,2 个 1,去掉所有个字,所以第五航就是 111221。 第六行读第五行,3 个 1,2 个 2,1 个 1,去掉所以个字,所以第六行就是 312
leetcode第38题
|
存储 算法
leetcode第43题
个位乘个位,得出一个数,然后个位乘十位,全部乘完以后,就再用十位乘以各个位。然后百位乘以各个位,最后将每次得出的数相加。十位的结果要补 1 个 0 ,百位的结果要补两个 0 。相加的话我们可以直接用之前的大数相加。直接看代码吧。
leetcode第43题
|
存储 算法
leetcode第49题
时间复杂度:两层 for 循环,再加上比较字符串,如果字符串最长为 K,总的时间复杂度就是 O(n²K)。 空间复杂度:O(NK),用来存储结果。 解法一算是比较通用的解法,不管字符串里边是大写字母,小写字母,数字,都可以用这个算法解决。这道题的话,题目告诉我们字符串中只有小写字母,针对这个限制,我们可以再用一些针对性强的算法。 下边的算法本质是,我们只要把一类的字符串用某一种方法唯一的映射到同一个位置就可以。
144 0
leetcode第49题
leetcode第31题
我们想几个问题。 要想使得数字变大,只要任意一位变大就可以。 要想得到刚好大于原来的数字,要变个位。 这里变大数字,只能利用交换。 如果从个位开始,从右往左进行,找一个比个位大的,交换过来,个位的数字交换到了更高位,由于个位的数字较小,所以交换过去虽然个位变大了,但数字整体变小了。例如 1 3 2,把 2 和 3 交换,变成 1 2 3,个位变大了,但整体数字变小了。 个位不行,我们再看十位,如果从十位左边找一个更大的数字交换过来,和个位的情况是一样的,数字会变小。例如 4 1 2 3,把 2 和 4 交换,2 1 4 3,数字会变小。如果从
leetcode第31题
leetcode第33题
问题出在,当数组剩偶数长度的时候,mid = (start + end)/ 2,mid 取的是左端点。上图的例子, mid > end, 更新 start = mid,start 位置并不会变化。那么下一次 mid 的值也不会变,就死循环了。所以,我们要更新 start = mid + 1。 综上,找最小值的下标的代码就出来了,同时,由于我们找的是位置 0 对应的下标,所以偏移就是最小值的下标.
leetcode第33题