LeetCode系列46—全排列

fkuner發表於2020-11-03

題意

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

問題分析

方法一:回溯+標記陣列used

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;
        vector<int> combine;
        vector<int> used(nums.size());
        fill(used.begin(), used.end(), 0);
        dfs(res, nums, used, combine, 0);  
        return res;          
    }

    void dfs(vector<vector<int>>& res, vector<int> nums, vector<int>& used, vector<int>& combine, int k){
        if(k == nums.size()){
            res.push_back(combine);
            return;
        }

        for(int i = 0; i < nums.size(); i++){
            if(used[i] == 0){
                used[i] = 1;
                combine.push_back(nums[i]);
                dfs(res, nums, used, combine, k+1);
                used[i] = 0;
                combine.pop_back();
            }
        }
    }

};

方法二:回溯+交換

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();

        List<Integer> output = new ArrayList<Integer>();
        for (int num : nums) {
            output.add(num);
        }

        int n = nums.length;
        backtrack(n, output, res, 0);
        return res;
    }

    public void backtrack(int n, List<Integer> output, List<List<Integer>> res, int first) {
        // 所有數都填完了
        if (first == n) {
            res.add(new ArrayList<Integer>(output));
        }
        for (int i = first; i < n; i++) {
            // 動態維護陣列
            Collections.swap(output, first, i);
            // 繼續遞迴填下一個數
            backtrack(n, output, res, first + 1);
            // 撤銷操作
            Collections.swap(output, first, i);
        }
    }
}

相關文章