46.Permutations - medium

给定一个数组,数组中的元素不重复,将数组中的元素全排列,输出全排列的组合。

Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

思路:(回溯 + 深度优先搜索
利用递归,将数组的下标元素不断的交换,记录下标变动的位置,当下标到达最后一个位置时,则将此时的数组加入到答案中。程序返回后,将之前变动交换的数组再交换回来,回复原状。详见Grandyang

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;
        permuteDFS(nums, 0, res);
        return res;
    }

    void permuteDFS(vector<int>& nums, int start, vector<vector<int>>& res) {
        if (start == (int)nums.size()) { 
            res.push_back(nums); return;
        }
        for (int i = start; i < (int)nums.size(); i++) {
            swap(nums[start], nums[i]);
            permuteDFS(nums, start + 1, res);
            swap(nums[start], nums[i]);
        }
    }
};

 

Java 版:

  • 深搜 + 回溯 的算法,回溯时重置现场,开启新一轮深搜;
  • 将数组的下标元素,不断的枚举交换,当下标到达最后一个位置时,将此时的数组,加入到结果集;
  • 注意:交换后迭代时,更新的是 start + 1,而不是 i+ 1
  • 因为:基于首元素的交换,将 start 后面的值,不断的与首元素 nums[start] 交换,当后面所有的元素都与 start 交换完后,移动 start,再将后面的所有元素,都来与 nums[start] 交换,这样就能穷举完所有可能的排列。
  • 如果是用 i+1 ,比如:[1,2,3] 当 start = 0, i=1 时,交换后变为 [2,1,3],此时若使用 i+1,start = 2,由于 start 只能和大于等于他的下标交换,则只能得到 [2,1,3] 而得不到 [2,3,1] 这个答案。有的人可能会想:那我 start=0, i=0,此时 i+1就可以取到 start=1 了,但是此时数组最前面是 [1,*,*] 以 1 开头,而对于 [2,*,*] 这种以 2 开头的数,就有错误了!!!

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        permuteDFS(nums, 0, res);
        return res;
    }
    private void permuteDFS(int[] nums, int start, List<List<Integer>> res){
        if(start == nums.length){
            List<Integer> tmp = new ArrayList<>(); // int 数组转为 List<Integer>
            for(int a : nums) tmp.add(a);
            res.add(tmp); return; // 加入结果集,返回上一层
        }
        for(int i = start; i < nums.length; i++){
            int number = nums[start]; // 交换两个下标的值
            nums[start] = nums[i];
            nums[i] = number;
            permuteDFS(nums, start + 1, res); // 注意这儿是 start + 1,而不是 i+1
            nums[i] = nums[start]; // 恢复原状,交换回来
            nums[start] = number;
        }
    }
}

 

posted @ 2020-05-27 17:53  星海寻梦233  阅读(136)  评论(0编辑  收藏  举报