:做题思路痕迹
class Solution {
List<String> temp = new ArrayList<>();
List<List<String>> res = new ArrayList<>();
// 记录皇后位置
List<Integer> list = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
backtrace(n, list);
return res;
}
// 维护一个二维数组?记录每个皇后的位置
// 判断是否合适的函数boolean
// n*n生成所有的list<String>
// int[][] nums = new int[n][n];
// for(int i = 0; i < n; i++){
// for(int j = 0; j < n; j++){
// nums[i][j]
// }
// }
// 用一个集合记录上面的所有层中皇后的位置,在本层不能出现相同的位置
public void backtrace(int n, List<Integer> list){
// StringBuilder str = new StringBuilder();
if(list.size() == n){
// 这里的list都满足0到n-1一个数仅一次。list中存的数代表列坐标,所以合法判断时就不用判断列,行也不会重复
if(isVaild(list, n)){
// 转化成string存到temp,在存到res中
temp = convert(list, n);
res.add(new ArrayList(temp));
temp = new ArrayList<>();
return;
}
// ans.add(new ArrayList(temp));
return;
}
for(int i = 0; i < n; i++){
// 这里
if(!list.contains(i)) {
list.add(i);
} else {
continue;
}
backtrace(n, list);
list.remove(list.size() - 1);
// str.append()
}
}
// 转化
public List<String> convert(List<Integer> list, int n){
char[] chs = new char[n];
for(int i = 0; i < n; i++){
// 外层for为了遍历list
for(int j = 0; j < n; j++){
// 遍历char
if(j == list.get(i)){
chs[j] = 'Q';
} else{
chs[j] = '.';
}
}
temp.add(new String(chs));
}
return temp;
}
//
public boolean isVaild(List<Integer> list, int n){
//
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
// 正对角线
if(i != j && i + list.get(j) == j + list.get(i)) return false;
// i的shang对角线判断
// if(i != j && i + j == list.get(i) + list.get(j)) return false;
// i的下对角线判断
// if(i < j && list.get(i) == list.get(j) + i - j) return false;
// 反对角线合并
if(i != j && list.get(i) + i == list.get(j) + j) return false;
/*
// i的左下对角线判断
if(i < j && list.get(i) + i == list.get(j) + j) return false;
// i的右上对角线判断
if(i > j && )
*/
}
}
return true;
}
// public boolean vaild(int n)
// 2代表皇后,1代表不能赋值,0可以
// hanshu:将二维数组的某个点的同行、同列、对角线上的0全变成1
// public void change(int[][] nums, int row, int col){
// // row
// for(int i = 0; i < nums.length; i++){
// if(nums[row][i] != 2){
// nums[row][i] = 1;
// }
// }
// // col
// for(int i = 0; i < nums.length; i++){
// if(nums[i][col] != 2){
// nums[i][col] = 1;
// }
// }
// // 斜线
// }
}
:通过后,修改,好看点
class Solution {
List<String> temp = new ArrayList<>();
List<List<String>> res = new ArrayList<>();
// 记录皇后位置
List<Integer> list = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
backtrace(n, list);
return res;
}
public void backtrace(int n, List<Integer> list){
// StringBuilder str = new StringBuilder();
if(list.size() == n){
// 这里的list都满足0到n-1一个数仅一次。list中存的数代表列坐标,所以合法判断时就不用判断列,行也不会重复
if(isVaild(list, n)){
// 转化成string存到temp,在存到res中
temp = convert(list, n);
res.add(new ArrayList(temp));
temp = new ArrayList<>();
return;
}
// ans.add(new ArrayList(temp));
return;
}
for(int i = 0; i < n; i++){
// 这里
if(!list.contains(i)) {
list.add(i);
} else {
continue;
}
backtrace(n, list);
list.remove(list.size() - 1);
}
}
// 转化
public List<String> convert(List<Integer> list, int n){
char[] chs = new char[n];
for(int i = 0; i < n; i++){
// 外层for为了遍历list
for(int j = 0; j < n; j++){
// 遍历char
if(j == list.get(i)){
chs[j] = 'Q';
} else{
chs[j] = '.';
}
}
temp.add(new String(chs));
}
return temp;
}
//
public boolean isVaild(List<Integer> list, int n){
//
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
// 正对角线
if(i != j && i + list.get(j) == j + list.get(i)) return false;
// 反对角线
if(i != j && list.get(i) + i == list.get(j) + j) return false;
}
}
return true;
}
}
// 我是用List<Integer>,数字型,为了更好地判断合法,但还要将list使用双层for转化成"."和"Q"。如果直接用List<String>,字符型,和一个二维数组判断,就不用“转化”这个开销了。能减小点时间开销?