一句话总结:今天的问题都是难题,没做出来。仅放题解。
原题链接:332 重新安排行程
看起来并不像是回溯的问题。题解源自官解。
class Solution {
private List<String> ans = new ArrayList<>();
Map<String, PriorityQueue<String>> map = new HashMap<>();
public List<String> findItinerary(List<List<String>> tickets) {
for (List<String> ticket : tickets) {
String from = ticket.get(0), to = ticket.get(1);
if (!map.containsKey(from)) {
map.put(from, new PriorityQueue<>());
}
map.get(from).offer(to);
}
dfs("JFK");
Collections.reverse(ans);
return ans;
}
private void dfs(String cur) {
while (map.containsKey(cur) && map.get(cur).size() > 0) {
String tmp = map.get(cur).poll();
dfs(tmp);
}
ans.add(cur);
}
}
原题链接:51 N皇后
回溯法,但并不好理解。
class Solution {
List<List<String>> ans = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
char[][] board = new char[n][n];
for (char[] row : board) {
Arrays.fill(row, '.');
}
backTrack(n, 0, board);
return ans;
}
private void backTrack(int n, int row, char[][] board) {
if (row == n) {
ans.add(Array2List(board));
return;
}
for (int col = 0; col < n; ++col) {
if (isValid(row, col, n, board)) {
board[row][col] = 'Q';
backTrack(n, row + 1, board);
board[row][col] = '.';
}
}
}
private List Array2List(char[][] board) {
List<String> ans = new ArrayList<>();
for (char[] row : board) {
ans.add(String.copyValueOf(row));
}
return ans;
}
private boolean isValid(int row, int col, int n, char[][] board) {
for (int i = 0; i < row; ++i) {
if (board[i][col] == 'Q') return false;
}
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; --i, --j) {
if (board[i][j] == 'Q') return false;
}
for (int i = row - 1, j = col + 1; i >= 0 && j < n; --i, ++j) {
if (board[i][j] == 'Q') return false;
}
return true;
}
}
原题链接:37 解数独
不好套回溯的模板,但是确实是回溯的思想。
class Solution {
public void solveSudoku(char[][] board) {
backTrack(board);
}
private boolean backTrack(char[][] board) {
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] != '.') continue;
for (char k = '1'; k <= '9'; ++k) {
if (isValid(i, j, k, board)) {
board[i][j] = k;
if (backTrack(board)) return true;
board[i][j] = '.';
}
}
return false;
}
}
return true;
}
private boolean isValid(int row, int col, char val, char[][] board) {
for (int i = 0; i < 9; ++i) {
if (board[row][i] == val) return false;
}
for (int j = 0; j < 9; ++j) {
if (board[j][col] == val) return false;
}
int startRow = (row / 3) * 3, startCol = (col / 3) * 3;
for (int i = startRow; i < startRow + 3; ++i) {
for (int j = startCol; j < startCol + 3; ++j) {
if (board[i][j] == val) return false;
}
}
return true;
}
}