52. N皇后 II
- N皇后
- 位运算
- DFS
看的网上别人的思路自己复现出来的结果。充分运用位运算和深度优先搜索。用位运算表示当前位置能否放置棋子的情况,0表示未放置棋子,1表示不能放置棋子。
比如一个8位的棋盘,未放置任何棋子时第一行为00000000,若第四个位置放置了棋子。则变为00010000。第二行可以放置棋子的情况变成00111000。这是由于第一行的第四个位置放置了棋子,因此这个棋子的左下角第二行第三位,正下方第二行第四位和右下角第二行第五位都无法放置棋子。顺延下去,左下角的左下角:第三行第二位;正下方的正下方:第三行第四位;因此思路中使用了三个变量,left表示左斜下方的不可放置位,right表示右斜下方的不可放置位,col表示垂直列的不可放置位。
按照上文的例子第一行为00010000。则第二行left为00100000由上一行左移一位得到,col为00010000,right为00001000由上一行右移一位得到,因此第二行的可放置位情况为(left | right | col),即00111000。left,right如同水纹散开分别进行左移右移。与此同时第二行插入新的棋子,即表示当前产生了新的“水纹”。因此newleft = (left | colbit) << 1;newright = (right | colbit) >> 1;colbit表示插入的新的棋子位置。因此之后的“水纹”是新“水纹”和旧“水纹”的融合。列的情况比较简单。
使用深度优先搜索(dfs)进行整个运算过程。深度优先搜索的过程中,判断可插入位置是否还有空余位置可以插入,如果没能执行完最后一行就已经没有位置了,说明之前的插入方法不对。程序执行完自然返回并且无任何操作。如果已经执行完成了最后一行if(row >= n),则最终的结果+1并且直接返回。
注意:移位运算符的优先级低于加减乘除,因此需要注意在需要的地方加上括号。
class Solution { |