看了一天回溯算法,一路調試代碼把自己都給轉暈了,看着問題解出來的代碼都很簡短,但是總覺得不太能理解,一路調試也知道有點像是:
從起始位置出發,如果前面有幾條岔路,那麼先選擇第一條,走下去,又有幾條岔路,再選擇第一條走下去,走過n個岔路口,一直都是選擇第一條走下去,一路到底之後;
返回上一個路口,選擇第二條一路走下去,又走過n個岔路口,到底之後,再返回上一個路口,選擇第二條重複下去。
其實就是把所有可能的情況通過樹的形式全部搜索出來,最後把所有符合的情況都列出來,或者如果是求最大值最小值,那麼就比較所有情況的最大值最小值,當然,這個可以在把每一種情況走到底的時候,就比較出來一個最大值或最小值。比較典型的就是8皇后問題,0-1揹包問題,還有就是正則表達式匹配問題。以下是前兩種問題的代碼,幾行代碼看了一整天,還感覺有點迷迷糊糊的,最後雖然是自己盲寫出來的,但是總覺得似乎不是理解寫出來的,而是看了一整天之後都把那十幾行代碼記熟了,我真是太菜了。
package com.freshbin.dataStructAndAlgo.chapter39.mycode;
/**
* 八皇后問題
* @date 2020/4/25 8:53
*/
public class EightQueen {
private int n; // n個皇后
int[] result;
int count; // 總的可能擺放結果數
public EightQueen(int n) {
this.n = n;
// n行n列的仿二維數組,數組中的值表示是第n列(從0開始數),比如a[0]=4,就表示第1行第5列已經放了皇后
// 這裏也可以用實際的二維數組,可能如果用二維數組會比較好理解一點,不過用一位數組比較取巧,代碼少寫一點
result = new int[n];
count = 0;
}
private void cal8queens() {
diguiCal(0); // 從第1行開始放皇后
}
private void diguiCal(int row) {
if(row == n) {
printQueen();
return;
}
// 從第一列往右邊判斷是否可以放置皇后,可以就直接放了,然後繼續下一行,
// 當下一行不滿足放置條件的話,再不斷回溯列,再回溯行
for(int col = 0; col < n; col++) {
if(canPlace(row, col)) {
result[row] = col; // 如果滿足條件,直接放置在該行該列
diguiCal(row+1); // 直接跳去下一行繼續走流程
}
}
}
/**
* 判斷當前行和列是否可以放置皇后
* 縱向比較,比較該行該列上方的行是否已經存在皇后,再比較該行該列左上角和右上角是否存在皇后
* @param row
* @param col
* @return
*/
private boolean canPlace(int row, int col) {
int leftUp = col - 1; // 左上角的列
int rightUp = col + 1; // 右上角的列
for(row = row - 1;row >= 0; row--) {
if(result[row] == col) {
return false;
}
if(leftUp >= 0 && result[row] == leftUp) {
return false;
}
if(rightUp < n && result[row] == rightUp) {
return false;
}
leftUp--;
rightUp++;
}
return true;
}
private void printQueen() {
// 打印結果
System.out.println("=======第" + ++count + "種結果===========");
for(int row = 0; row < result.length; row++) {
for(int col = 0; col < n; col++) {
if(result[row] == col) {
System.out.print("Q ");
} else {
System.out.print("* ");
}
}
System.out.println();
}
}
public static void main(String[] arg) {
EightQueen eightQueen = new EightQueen(8);
eightQueen.cal8queens();
System.out.println(Integer.MIN_VALUE);
}
}
package com.freshbin.dataStructAndAlgo.chapter39.mycode;
import java.util.HashMap;
/**
* @author freshbin
* @date 2020/4/25 12:02
*/
public class PackageSolution {
public HashMap<String, Integer> cacheMap;
public int canPackageWeight;
public int packageCurrentWeight;
public PackageSolution(int canPackageWeight) {
cacheMap = new HashMap<>();
this.canPackageWeight = canPackageWeight;
this.packageCurrentWeight = 0;
}
/**
* @param currentIndex
* @param currentWeight
* @param items
*/
public void knapsack(int currentIndex, int currentWeight, int[] items) {
if(currentIndex >= items.length || currentIndex >= canPackageWeight) {
if(currentWeight <= canPackageWeight) {
packageCurrentWeight = Math.max(currentWeight, packageCurrentWeight);
return;
}
}
String key = currentIndex + "-" + currentWeight;
if(cacheMap.containsKey(key)) {
return;
}
cacheMap.put(key, 1);
knapsack(currentIndex+1, currentWeight, items);
if(currentWeight + items[currentIndex] <= canPackageWeight) {
knapsack(currentIndex+1, currentWeight+items[currentIndex], items);
}
}
public static void main(String[] arg) {
int[] a = {2, 2, 4, 6, 3};
PackageSolution packageSolution = new PackageSolution(9);
packageSolution.knapsack(0, 0, a);
System.out.println(packageSolution.packageCurrentWeight);
}
}