zoukankan      html  css  js  c++  java
  • 46.Permutations

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

    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;
            }
        }
    }
  • 相关阅读:
    xshell常用命令
    linux传输文件命令: rz 和 sz
    使用openssh-clients的scp命令来传输文件
    RabbitMQ初学之二:直接发送消息到队列
    [App]华为P6设置与Xamarin Studio连通测试
    [Boost]图形处理库Boost::Polygon
    [App]Taste VS2015 && Android Studio
    [Linux&Vim]输入输出流
    [SSD大法好]神舟K480-I5-D3鸟枪换炮M6S
    [IoLanguage]Io Tutorial[转]
  • 原文地址:https://www.cnblogs.com/luo-c/p/12974962.html
Copyright © 2011-2022 走看看