题目描述 实现 pow(x , n ) ,即计算 x 的 n 次幂函数。
题解 还是2的幂次比较好用。
1 2 3 4 5 6 7 8 9 10 double myPow (double x, int n) { if (x == 1 )return 1 ; double res = 1 ; for (int i = n; i != 0 ; i /= 2 ) { if (i % 2 )res *= x; x *= x; } return n < 0 ? 1 / res : res; }
题目描述 n 皇后问题研究的是如何将 n 个皇后放置在 n ×n 的棋盘上,并且使皇后彼此之间不能相互攻击,即任意两个皇后 都不能处于同一行、同一列或同一斜线上。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
题解 终究躲不过。
n=1时返回1,n皇后问题当n大于等于4才有讨论意义,而且不只有一个解决方案;递归回溯找到每一种解决方案;
行数要记得往下移,不要走回头路,不然会死循环。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 bool *heng, *shu, *pie, *na;vector <string > model;void dfs (vector <vector <string >>& res,int count,int n,int row) { if (count==n){ res.push_back(model); return ; } for (int i = row; i < n; i++) { for (int j = 0 ; j < n; j++) { if (heng[i]) { if (shu[j] && pie[i + j] && na[n - 1 - i + j]) { model[i][j] = 'Q' ; heng[i] = false ; shu[j] = false ; pie[i + j] = false ; na[n - 1 - i + j] = false ; dfs(res, count + 1 , n,i+1 ); model[i][j] = '.' ; heng[i] = true ; shu[j] = true ; pie[i + j] = true ; na[n - 1 - i + j] = true ; } } else break ; } } } vector <vector <string >> solveNQueens(int n) { if (n == 1 )return {{"Q" }}; if (n < 4 )return {}; vector <vector <string >> res; string s = "" ; for (int i = 0 ; i < n; i++) s = s + '.' ; for (int i = 0 ; i < n; i++) model.push_back(s); heng = new bool [n]; shu = new bool [n]; int t = 2 * n - 1 ; pie = new bool [t]; na = new bool [t]; for (int i = 0 ; i < n; i++) { heng[i] = true ; shu[i] = true ; } for (int i = 0 ; i < t; i++) { pie[i] = true ; na[i] = true ; } dfs(res, 0 , n, 0 ); return res; }
执行用时 :108 ms, 在所有 C++ 提交中击败了6.45%的用户
内存消耗 :9.7 MB, 在所有 C++ 提交中击败了98.99%的用户
时间复杂度太差了,再剪剪枝。
本地没错,交到网上就报错:Heap-buffer-overflow。最后发现是斜线数量没注意。LeetCode对数组越界检查的比较严。
还是位运算效率最高。明天学吧。
题目描述 给定一个整数 n ,返回 n 皇后不同的解决方案的数量。
题解 棋盘上棋子的位置信息用一个一维数组来表示就好了,下标表示行数,值表示列数。如果两个格子处在同一斜线上,他们的横纵坐标满足:abs(row1-row2)=abs(col1-col2)。
非递归方法的一个重要问题时何时回溯及如何回溯的问题。程序首先对N行中的每一行进行探测,寻找该行中可以放置皇后的位置,具体方法是对该行的每一列进行探测,看是否可以放置皇后,如果可以,则在该列放置一个皇后,然后继续探测下一行的皇后位置。如果已经探测完所有的列都没有找到可以放置皇后的列,此时就应该回溯,把上一行皇后的位置往后移一列,如果上一行皇后移动后也找不到位置,则继续回溯直至某一行找到皇后的位置或回溯到第一行,如果第一行皇后也无法找到可以放置皇后的位置,则说明已经找到所有的解程序终止。如果该行已经是最后一行,则探测完该行后,如果找到放置皇后的位置,则说明找到一个结果,打印出来。但是此时并不能再此处结束程序,因为我们要找的是所有N皇后问题所有的解,此时应该清除该行的皇后,从当前放置皇后列数的下一列继续探测。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 int totalNQueens (int n) { int * a; a = new int [n]; for (int i = 0 ; i < n; i++) a[i] = -20 ; int res = 0 ; int i = 0 , j = 0 ; while (i < n) { while (j < n) { bool valid = true ; for (int k = 0 ; k < n; k++) { if (j == a[k] || abs (i - k) == abs (j - a[k])) { valid = false ; break ; } } if (valid) { a[i] = j; j = 0 ; break ; } ++j; } if (a[i] == -20 ) { if (i == 0 ) break ; --i; j = a[i] + 1 ; a[i] = -20 ; continue ; } if (i == n - 1 ) { res++; j = a[i] + 1 ; a[i] = -20 ; continue ; } i++; } return res; }
需要注意初始化a[i]的值时,a[i]的绝对值要比n大,否则在判断该位置是否有效的abs函数处会出现错误。
参考:https://blog.csdn.net/sinat_34166518/article/details/80096219