算法套路學習之回溯算法-----包括常見題目記錄

來源:https://www.cnblogs.com/labuladong/p/12320463.html
我是看這個大佬的博客學習到的,下面我自己總結一下,並且記錄一下遇到的使用回溯的題目,驗證一下這個套路的可行性。一直比較討厭這種題,因爲沒有總結出一套框架來。

一.需要思考的問題

解決一個回溯算法題,只需要以下三點:

  1. 路徑:也就是已經做出的選擇。
  2. 選擇列表:也就是你當前可以做的選擇
  3. 結束條件:也就是到達決策樹底層,無法再做選擇的條件

其實我看到這個也是一臉懵逼的,但是後來看例子就明白了,下面是算法的框架:

result = []
def backtrack(路徑, 選擇列表):
    if 滿足結束條件:
        result.add(路徑)
        return
    
    for 選擇 in 選擇列表:
        做選擇
        backtrack(路徑, 選擇列表)
        撤銷選擇

簡單解釋:首先result是在這個函數之外,屬於一個全局的變量,是保存結果的,這個函數比較重要。


二.例題

1.全排列

給定一個 沒有重複 數字的序列,返回其所有可能的全排列。這是LeetCode的46題,非常常見,我做了幾次還是經常寫不對,這太難受了,原理文章中已經講得很清楚,下面我自己實現一下:

class Solution {
    List<List<Integer>> res = new LinkedList<>();
    public List<List<Integer>> permute(int[] nums) {
         // 記錄「路徑」
        LinkedList<Integer> track = new LinkedList<>();
        backtrack(nums, track);
        return res;
    }

    private void backtrack(int[] nums, LinkedList<Integer> track){
        //寫結束條件,就是路徑長度跟選擇列表一樣的時候
        if(track.size() == nums.length){
            res.add(new LinkedList(track));
            return;
        }

        for (int i = 0; i < nums.length; i++) {
        //如果已經選了就過濾掉
        if (track.contains(nums[i]))
            continue;
        //做選擇
        track.add(nums[i]);

        //進入下一層決策樹
        backtrack(nums, track);

        //取消選擇
        track.removeLast();
    }
    }
}

解釋一下:

這是決策數結構:
在這裏插入圖片描述

  1. 首先建立一個成員變量res,是一個嵌套的List,對應上面框架的result,這就是結果
  2. 確定什麼是路徑,什麼是路徑呢,其實就是我這個結果其中一個List,這個List保存着一條完整的路徑,也就是一個排列,比如【1,2,3】這三個數其中一個排列是3,2,1,這個【3,2,1】就是一條路徑,它是結果的一部分
  3. 重點說一下選擇和選擇列表這塊。在這個題裏頭,選擇是什麼呢,其實就是選不選這個數,比如我現在剛選完1,下面可以選擇2和3,【2,3】就是選擇列表,1已經不能選了,因爲已經選過了,所以通過continue過濾掉。

2.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章