提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
如何理解回溯法的搜索过程? 什么时候用startIndex,什么时候不用? 如何去重?如何理解“树枝去重”与“树层去重”? 去重的几种方法? 如何理解二维递归?
一、力扣332. 重新安排行程
class Solution {
private Deque<String> res;
private 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)){//防止出现null
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<String, Map<String, Integer>>();
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<>();//升序Map
temp.put(t.get(1), 1);
}
map.put(t.get(0), temp);
}
res.add("JFK");
backTracking(tickets.size());
return new ArrayList<>(res);
}
}
二、力扣51. N 皇后
在这里插入代码片class Solution {
List<List<String>> res = new ArrayList<>();
char[][] path;
public List<List<String>> solveNQueens(int n) {
path = new char[n][n];
for(char[] c : path){
Arrays.fill(c,'.');
}
fun(n,0);
return res;
}
public void f(int n){
List<String> p = new ArrayList<>();
for(int i = 0; i < n; i ++){
StringBuilder s = new StringBuilder();
for(int j = 0; j < n; j ++){
s.append(path[i][j]);
}
p.add(s.toString());
}
res.add(new ArrayList<>(p));
}
public void fun(int n,int row){
if(row >= n){
f(n);
return;
}
for(int i = 0; i < n; i ++){
if(isOk(row,i,n)){
path[row][i] = 'Q';
fun(n,row+1);
path[row][i] = '.';
}
}
}
public boolean isOk(int r, int l, int n){
for(int i = 0; i < n; i ++){
if(path[r][i] == 'Q'){
return false;
}
}
for(int i = 0; i < n; i ++){
if(path[i][l] == 'Q'){
return false;
}
}
for(int i = r-1, j = l-1; i >= 0 && j >= 0;i--,j--){
if(path[i][j] == 'Q'){
return false;
}
}
for(int i = r-1, j = l+1; i >= 0 && j <= n-1; i --, j ++){
if(path[i][j] == 'Q'){
return false;
}
}
return true;
}
}
三、力扣37. 解数独
class Solution {
public void solveSudoku(char[][] board) {
fun(board);
}
public boolean fun(char[][] board){
for(int i = 0; i < board.length; i ++){
for(int j = 0; j < board.length; j ++){
if(board[i][j] != '.'){
continue;
}
for(char k = '1'; k <= '9'; k ++){
if(isOk(board,i,j,k)){
board[i][j] = k;
if(fun(board)){
return true;
}
board[i][j] = '.';
}
}
return false;
}
}
return true;
}
public boolean isOk(char[][] board, int r, int l, char k){
for(int i = 0; i < board.length; i ++){
if(board[r][i] == k){
return false;
}
}
for(int i = 0; i < board.length; i ++){
if(board[i][l] == k){
return false;
}
}
for(int i = r/3*3; i < (r/3+1)*3; i ++){
for(int j = l/3*3; j < (l/3+1)*3; j ++){
if(board[i][j] == k){
return false;
}
}
}
return true;
}
}
本文详细介绍了如何使用回溯法解决力扣编程题目,包括重新安排行程(332)、N皇后(51)以及解数独(37),涉及递归、去重策略以及二维逻辑的应用。
881

被折叠的 条评论
为什么被折叠?



