1. 程式人生 > 實用技巧 >leetcode刷題記錄:回溯演算法注意事項

leetcode刷題記錄:回溯演算法注意事項

leetcode 46題:

給定一個沒有重複數字的序列,返回其所有可能的全排列。

輸入: [1,2,3]
輸出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

思路就是按照這張圖進行窮舉

class Solution {
    private List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> permute(int[] nums) {      
        List
<Integer> path = new ArrayList<>(); backTrack(path, nums); return res; } private void backTrack(List<Integer> path, int[] nums){ if(path.size() == nums.length){ res.add(new ArrayList<>(path)); // 注意要對path進行復制 return
; } for(int num : nums){ if(path.contains(num)) continue; path.add(num); backTrack(path, nums); path.remove(path.size() - 1); } } }

程式碼按照回溯演算法的典型框架實現,但是需要注意的是,在遞迴結束的時候,很容易犯如下錯誤

if(path.size() == nums.length){
            res.add(path);          
            
return; }

這樣的話,程式碼的輸出結果為[[],[],[],[],[],[],[]]

當按照1->2->3這條路線遍歷到最底層的時候,path = [1,2,3]確實被存進了res中,但是被忘了存的是path這個指標,在後來的遍歷過程中path指向的堆記憶體的內容會一直修改,因為回溯演算法的精髓是通過

path.remove(path.size() - 1)

將路徑的最後一個節點刪除去返回上一個節點,返回一次刪一個,最終返回到最高層的時候,path指向的內容就為空了,所以為了儲存遍歷的結果,要講path的內容複製一份。