回溯步骤:
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
这道题虽然是简单题,但也把我折腾个够呛,奇淫技巧就不说了,老老实实的回溯就行了。可就是简单的回溯我一开始也写不好,一开始简单的想着每次回溯前删除一个数,回溯后加回来,这个方法太复杂,其次时间复杂度也奇高,其实只需要一个bool数组记录每次选中的数即可。
感觉每次都会忘记以空间换时间的方法/(ㄒoㄒ)/~~
class Solution {
public:
vector<vector<int>> res;
vector<int> tmp;
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> flag(nums.size(),false);
backtrack(nums,flag);
return res;
}
void backtrack(vector<int>& nums,vector<bool>& flag)
{
if(tmp.size()==nums.size())
{
res.push_back(tmp);
return;
}
for(int i=0;i<nums.size();i++)
{
if(flag[i]) continue;
tmp.push_back(nums[i]);
flag[i]=true;
backtrack(nums,flag);
flag[i]=false;
tmp.pop_back();
}
}
};
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
经典的回溯问题,回溯前只需要考虑能否放下棋子,分别检查纵列,左斜线,右斜线,横列无需考虑,因为我们遍历的就是横列,每次回溯后会去掉这颗棋子。
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> ret;
vector<string> flag(n, string(n,'.'));
backtrace(ret, flag, 0);
return ret;
}
void backtrace(vector<vector<string>>& ret, vector<string>& flag, int n)
{
if(n == flag.size()){
ret.push_back(flag);
}
int size = flag.size();
for(int i = 0; i < size; i++){
bool have = false;
for(int j = 0; j < size; j++){
if(flag[j][i] == 'Q'){
have = true;
break;
}
}
if(have)
continue;
int j = n;
int k = i;
while(j >= 0 && k >= 0 && j < size && k < size){
if(flag[j][k] == 'Q'){
have = true;
break;
}
j++;
k++;
}
if(have)
continue;
j = n;
k = i;
while(j >= 0 && k >= 0 && j < size && k < size){
if(flag[j][k] == 'Q'){
have = true;
break;
}
j--;
k--;
}
if(have)
continue;
j = n;
k = i;
while(j >= 0 && k >= 0 && j < size && k < size){
if(flag[j][k] == 'Q'){
have = true;
break;
}
j--;
k++;
}
if(have)
continue;
j = n;
k = i;
while(j >= 0 && k >= 0 && j < size && k < size){
if(flag[j][k] == 'Q'){
have = true;
break;
}
j++;
k--;
}
if(have)
continue;
flag[n][i] = 'Q';
backtrace(ret, flag, n+1);
flag[n][i] = '.';
}
}
};
为了提高时间效率,加了很多冗余代码,所以会有点长,/(ㄒoㄒ)/~~