今天是心碎的一天,三道困难题打的我体无完肤,肝肠寸断
332题:重新安排行程
这个题很有趣,复习了一下lamda表达式的用法,先把票按终点进行排序,然后再利用used数组去重代码如下:
LinkedList<String> res;
LinkedList<String> path = new LinkedList<>();
public List<String> findItinerary(List<List<String>> tickets) {
Collections.sort(tickets, (a, b) -> a.get(1).compareTo(b.get(1)));
path.add("JFK");
boolean[] used = new boolean[tickets.size()];
backTracking((ArrayList) tickets, used);
return res;
}
public boolean backTracking(ArrayList<List<String>> tickets, boolean[] used) {
if (path.size() == tickets.size() + 1) {
res = new LinkedList(path);
return true;
}
for (int i = 0; i < tickets.size(); i++) {
if (!used[i] && tickets.get(i).get(0).equals(path.getLast())) {
path.add(tickets.get(i).get(1));
used[i] = true;
if (backTracking(tickets, used)) {
return true;
}
used[i] = false;
path.removeLast();
}
}
return false;
}
51:N 皇后
这个还是比较简单的,相对于上一题来说的话,可能难点对于学Java的同学来说在于两个辅助函数的思考,一个辅助函数是判定是否有效,另外一个是二维数组转List的函数,然后就是按行遍历放入Q代码如下:
List<List<String>> res = new ArrayList();
public List<List<String>> solveNQueens(int n) {
char[][] chessboard = new char[n][n];
for (char[] c : chessboard) {
Arrays.fill(c, '.');
}
backTracking(chessboard,n,0);
return res;
}
public void backTracking(char[][] chessboard, int n,int row){
if(row==n){
res.add(Array2List(chessboard));
return;
}
for(int i=0;i<n;i++){
if(isValid(row,i,n,chessboard)){
chessboard[row][i] = 'Q';
backTracking(chessboard,n,row+1);
chessboard[row][i] = '.';
}
}
return;
}
public List Array2List(char[][] chessboard) {
List<String> list = new ArrayList<>();
for (char[] c : chessboard) {
list.add(String.copyValueOf(c));
}
return list;
}
public boolean isValid(int row, int col, int n, char[][] chessboard) {
// 检查列
for (int i=0; i<row; ++i) { // 相当于剪枝
if (chessboard[i][col] == 'Q') {
return false;
}
}
// 检查45度对角线
for (int i=row-1, j=col-1; i>=0 && j>=0; i--, j--) {
if (chessboard[i][j] == 'Q') {
return false;
}
}
// 检查135度对角线
for (int i=row-1, j=col+1; i>=0 && j<=n-1; i--, j++) {
if (chessboard[i][j] == 'Q') {
return false;
}
}
return true;
}
37:解数独
很难,即使刚刚做完N皇后这个题也难的离谱两个for循环嵌套下的回溯算法,有一个细节就是只需要一个返回值时就是有返回的,多个时就是void代码如下:
public void solveSudoku(char[][] board) {
backTracking(board);
}
public 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 k = '1';k<='9';k++){
if(isValid(i,j,k,board)){
board[i][j] = k;
boolean re = backTracking(board);
if(re==true){return true;}
board[i][j] = '.';
}
}
return false;
}
}
return true;
}
public boolean isValid(int row, int col, char n, char[][] chessboard) {
int startRow = (row / 3) * 3;
int startCol = (col / 3) * 3;
for (int i = startRow; i < startRow + 3; i++){
for (int j = startCol; j < startCol + 3; j++){
if (chessboard[i][j] == n){
return false;
}
}
}
for (int i=0; i<9; ++i) {
if (chessboard[i][col] == n ) {
return false;
}
}
for (int i=0; i<9; ++i) {
if (chessboard[row][i] == n ) {
return false;
}
}
return true;
}