leetcode刷題記錄:回溯演算法注意事項
阿新 • • 發佈:2020-08-13
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的內容複製一份。