zoukankan      html  css  js  c++  java
  • 【LeetCode】046. Permutations

    题目:

    Given a collection of distinct numbers, return all possible permutations.

    For example,
    [1,2,3] have the following permutations:

    [
      [1,2,3],
      [1,3,2],
      [2,1,3],
      [2,3,1],
      [3,1,2],
      [3,2,1]
    ]
    

      

    题解:

      之前解过Next Permutation,故这个题可以重复调用nextPermutation函数产生全排列

    Solution 1 ()

    class Solution {
    public:
        void nextPermutation(vector<int>& nums) {
            int n = nums.size();
            for(int i=n-2; i>=0; --i) {
                if(nums[i]>=nums[i+1]) continue;
                int j = n-1;
                for(; j>i; --j) {
                    if(nums[j]>nums[i]) break;
                }
                swap(nums[i], nums[j]);
                reverse(nums.begin()+i+1, nums.end());
                return;            
            }
            reverse(nums.begin(), nums.end());
        }
        vector<vector<int>> permute(vector<int>& nums) {
            vector<vector<int>> vv;
            vector<int> v = nums;
            vv.push_back(v);
            nextPermutation(v);
            while(v != nums) {
                vv.push_back(v);
                nextPermutation(v);
            }
            return vv;
        }
    };

      其实这个问题很容易想到递归的解法

      for the length of n, the permutations can be generated by
    (1) Swap the 1st element with all the elements, including itself.
    (2) Then the 1st element is fixed, Go to the next element.
    (3) Until the last element is fixed. Output.
    It's more clear in the figure above. The key point is to make the big problem into smaller problem, here is how to convert the length n permutation into length n-1 permutation problem. from here and here

    Solution 2 ()

    class Solution {
    public:
        vector<vector<int> > permute(vector<int> &nums) {
            vector<vector<int> > result;        
            permuteRecursive(nums, 0, result);
            return result;
        } 
        // permute nums[begin..end]
        // invariant: nums[0..begin-1] have been fixed/permuted
        void permuteRecursive(vector<int> &nums, int begin, vector<vector<int> > &result)    {
            if (begin >= nums.size()) {
                // one permutation instance
                result.push_back(nums);
                return;
            }
            for (int i = begin; i < nums.size(); i++) {
                swap(nums[begin], nums[i]);
                permuteRecursive(nums, begin + 1, result);
                // reset
                swap(nums[begin], nums[i]);
            }
        }
    };

      利用深度优先遍历遍历所有情况,DFS方法,用到一个数组来标记某个数字是否访问过,然后在DFS递归函数从的循环应从头开始,而不是从level开始,这是和Combinations 组合项不同的地方。

    from here 

    Solution 3 ()

    class Solution {
    public:
        vector<vector<int> > permute(vector<int> &nums) {
            vector<vector<int> > res;
            vector<int> out;
            vector<int> visited(nums.size(), 0);
            permuteDFS(nums, 0, visited, out, res);
            return res;
        }
        void permuteDFS(vector<int> &nums, int level, vector<int> &visited, vector<int> &out, vector<vector<int> > &res) {
            if (level == nums.size()) res.push_back(out);
            else {
                for (int i = 0; i < nums.size(); ++i) {
                    if (visited[i] == 0) {
                        visited[i] = 1;
                        out.push_back(nums[i]);
                        permuteDFS(nums, level + 1, visited, out, res);
                        out.pop_back();
                        visited[i] = 0;
                    }
                }
            }
        }
    };

       思路: from here

    当n=1时,数组中只有一个数a1,其全排列只有一种,即为a1

    当n=2时,数组中此时有a1a2,其全排列有两种,a1a2和a2a1,那么此时我们考虑和上面那种情况的关系,我们发现,其实就是在a1的前后两个位置分别加入了a2

    当n=3时,数组中有a1a2a3,此时全排列有六种,分别为a1a2a3, a1a3a2, a2a1a3, a2a3a1, a3a1a2, 和 a3a2a1。那么根据上面的结论,实际上是在a1a2和a2a1的基础上在不同的位置上加入a3而得到的。

    _ a_ a_ : a3a1a2, a1a3a2, a1a2a3

    _ a_ a_ : a3a2a1, a2a3a1, a2a1a3

    Solution 4 ()

    class Solution {
    public:
        vector<vector<int> > permute(vector<int> &nums) {
            if (nums.empty()) return vector<vector<int> >(1, vector<int>());
            vector<vector<int> > res;
            int first = nums[0];
            nums.erase(nums.begin());
            vector<vector<int> > words = permute(nums);
            for (auto &a : words) {
                for (int i = 0; i <= a.size(); ++i) {
                    a.insert(a.begin() + i, first);
                    res.push_back(a);
                    a.erase(a.begin() + i);
                }
            }   
            return res;
        }
    };
  • 相关阅读:
    [转](五)unity4.6Ugui中文教程文档-------概要-UGUI Interaction Components
    [转](四)unity4.6Ugui中文教程文档-------概要-UGUI Visual Components
    [转](三)unity4.6Ugui中文教程文档-------概要-UGUI Basic Layout
    [转](二)unity4.6Ugui中文教程文档-------概要-UGUI Canvas
    [转](一)unity4.6Ugui中文教程文档-------概要
    Blog List
    引用总结
    动态申请二维数组
    malloc/free
    memset
  • 原文地址:https://www.cnblogs.com/Atanisi/p/6766880.html
Copyright © 2011-2022 走看看