N 皇后 LeetCode 51
题目链接:[LeetCode 51 - 困难]
思路
主要解决方式:1.设置一个回溯的方法2.判断是否存在同一行或同一列或同一斜线上
回溯:
class Solution {
List<List<String>> result = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
char[][] chessboard = new char[n][n];
for(char[] c:chessboard){
Arrays.fill(c,'.');
}
backtracking(0,n,chessboard);
return result;
}
private List Array2List(char[][] chessboard){
List<String> list = new ArrayList<>();
for(char[] c:chessboard){
list.add(String.copyValueOf(c));
}
return list;
}
private void backtracking(int row,int n,char[][] chessboard){
if(row == n){
result.add(Array2List(chessboard));
return;
}
for(int col = 0;col < n;col++){
if(isValid(row,col,n,chessboard)){
chessboard[row][col] = 'Q';
backtracking(row+1,n,chessboard);
chessboard[row][col] = '.';
}
}
}
private boolean isValid(int row,int col,int n,char[][] chessboard){
for(int i=0;i<row;i++){
if(chessboard[i][col]=='Q'){
return false;
}
}
for(int i=row-1,j=col-1;i>=0&&j>=0;i--,j--){
if(chessboard[i][j]=='Q'){
return false;
}
}
for(int i=row-1,j=col+1;i>=0&&j<=n-1;i--,j++){
if(chessboard[i][j]=='Q'){
return false;
}
}
return true;
}
}
解数独 LeetCode 37
题目链接:[LeetCode 37 - 困难]
思路
int iIndex = (row / 3) *3;
int jIndex = (col / 3) *3;
回溯:
class Solution {
public void solveSudoku(char[][] board) {
backtracking(board);
}
private boolean backtracking(char[][] board){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if (board[i][j] != '.'){
continue;
}
for(char num='1';num<='9';num++)
if(isValid(i,j,board,num)){
board[i][j] = num;
if(backtracking(board)){
return true;
}
board[i][j] = '.';
}
return false;
}
}
return true;
}
private boolean isValid(int row,int col,char[][] board,char num){
for(int i=0;i<9;i++){
if(board[i][col]==num){
return false;
}
}
for(int j=0;j<9;j++){
if(board[row][j]==num){
return false;
}
}
int iIndex = (row / 3) *3;
int jIndex = (col / 3) *3;
for(int i=iIndex;i<iIndex+3;i++){
for(int j=jIndex;j<jIndex+3;j++){
if(board[i][j]==num){
return false;
}
}
}
return true;
}
}
非递减子序列 LeetCode 491
题目链接:[LeetCode 491 - 中等]
思路
使用HashSet去重。
回溯:
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new LinkedList<>();
public List<List<Integer>> findSubsequences(int[] nums) {
backtracking(nums,0);
return result;
}
private void backtracking(int[] nums,int index){
if(path.size()>=2){
result.add(new ArrayList(path));
}
HashSet<Integer> hs = new HashSet<>();
for(int i=index;i<nums.length;i++){
if(!path.isEmpty()&&path.getLast()>nums[i] || hs.contains(nums[i])){
continue;
}
hs.add(nums[i]);
path.add(nums[i]);
backtracking(nums,i+1);
path.removeLast();
}
}
}
重新安排行程 LeetCode 332
题目链接:[LeetCode 332 - 困难]
思路
所想的思路会导致80例超时
回溯:
class Solution {
Deque<String> res;
Map<String,Map<String,Integer>> map;
private boolean backTracking(int ticketNum){
if(res.size()==ticketNum+1){
return true;
}
String last = res.getLast();
if(map.containsKey(last)){
for(Map.Entry<String,Integer> target:map.get(last).entrySet()){
int count = target.getValue();
if(count>0){
res.add(target.getKey());
target.setValue(count-1);
if(backTracking(ticketNum))return true;
res.removeLast();
target.setValue(count);
}
}
}
return false;
}
public List<String> findItinerary(List<List<String>> tickets) {
map = new HashMap<>();
res = new LinkedList<>();
for(List<String> t:tickets){
Map<String,Integer> temp;
if(map.containsKey(t.get(0))){
temp = map.get(t.get(0));
temp.put(t.get(1),temp.getOrDefault(t.get(1),0)+1);
}else{
temp = new TreeMap<>();
temp.put(t.get(1),1);
}
map.put(t.get(0),temp);
}
res.add("JFK");
backTracking(tickets.size());
return new ArrayList<>(res);
}
}