16 Arrangements with Repeating Elements

Original title URL: https://www.lintcode.com/zh-cn/problem/permutations-ii/#

Given a list with repeating numbers, find all the different permutations of the list.

Sample

Given a list  [1,2,2], the different permutations are:

[
  [1,2,2],
  [2,1,2],
  [2,2,1]
]
challenge 

Complete this problem using recursion and non-recursion respectively.

Label 
 
method 1.
Whether recursive or non-recursive, you can set up a judgment function to judge whether there is an array (arrangement) currently to be inserted in the result. To put it bluntly, if the current arrangement does not overlap with the existing arrangement, push it to the result.
 
This judgment function is very easy to write, two for loops can be done, reference: https://www.cnblogs.com/libaoquan/p/6986365.html 
 
I copied it directly:
 bool isExist(vector<int> &nums, vector<vector<int> > &result) {
        int size = result.size();
        if(size == 0)
            return false;
        for(int i=0; i<size; i++) {
            if(isSameNums(nums, result[i])) {
                return true;
            }
        }
        return false;
    }

    bool isSameNums(vector<int> &nums1, vector<int> &nums2) {
        int size = nums1.size();
        for(int i=0; i<size; i++) {
            if(nums1[i] != nums2[i]) {
                return false;
            }
        }
        return true;
    }

I feel that the design of the subroutine can improve the readability and facilitate understanding, and I worship the big guy.

In fact, when programming, you can turn big problems into small problems, solve them step by step, and write specific functions for the realization of each function (repeatedly use a certain function or facilitate understanding).

 
Method 2. Recursive Reference: http://www.cnblogs.com/jcliBlogger/p/4625828.html
 Referring to the full arrangement, if there are repeated elements in the array, the adjacent repeated elements are equivalent to one element, because there is only one kind of full arrangement, such as [2,2] in the example, this part of the full arrangement is no different from [2] , of course, the same is true for a few more 2s.
So you can sort first so that the same elements in the array are adjacent. Then refer to the idea of ​​​​full arrangement, the difference is that if nums[i] is the same as nums[i] in the last loop, that is, nums[start], jump out and make the next judgment.
Note that the block inside the loop does not need to be swapped after the recursive call.
 
AC code:
 
class Solution {
public:
    /*
     * @param :  A list of integers
     * @return: A list of unique permutations
     */
    vector<vector<int>> permuteUnique(vector<int> &nums) {
        // write your code here
        vector<vector<int>> result;
    if (nums.empty())
    {
        result.push_back(nums);
        return result;
    }
    sort(nums.begin(),nums.end());
    perm(nums,0,result);
    return result;
    }
    
    
    void perm(vector<int> nums,int start,vector<vector<int>> &result)
{
    if (start==nums.size()-1)
    {
        result.push_back(nums);
    }
    for (int i=start;i<(int)nums.size();i++)
    {
        if (i==start||nums[i]!=nums[start])
        {
            swap(nums[start],nums[i]); // nums[start] is nums[i] of the last loop; 
            perm(nums,start+ 1 ,result);
        
        }
    }
}

};

 

 
 
 
Other ideas:

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324848702&siteId=291194637