Permutation (LeetCode)

Question:

https://leetcode.com/problems/permutations-ii/

 

解答:

需要考虑有值重复的情况,跟Permutations I一样的解法,只是需要考虑如何去除重复的 情况。

两种解法:

1. recursive:

这种情况不需要排序。

P(N) = P(1)+P(N-1),就是说当前N个结点的Permutation是第一个结点和后面N-1个结点的Permutation的组合。第一个结点的取值可以是数组的任何一个。所以依次交换,剩下的N-1点同法递归求Permutation. 

重复的情况,如果当前点值是K,则后面遇到点值为K的时候需要略过,因为两者交换没有区别。同时如果后面点值是Q,但是Q以前已经跟K交换过了,这时也需要略过。 

 

2. Iterative:

需要事先把数组排好序。 

从后面往前找到第一个数是小于后面的数的,设为i,然后重新从后面开始找第一个大于num[i]的数,设为j,因为(i, i+1)是(i,n-1)唯一一组递增的数,所以(i+1, n-1)都是递减的。i,j交换,然后反转(i+1, n-1),这样数组就是正序的。

这样的做的道理是,比如当前数组是:

1 2 3 4 5,后面4位处理到最后会变成1 5 4 3 2,这时我们需要1和2交换,相当于重新开始处理后4位,所以需要重置后4位,这样才能重新开始计算。

 

class Solution {
public:
    vector<vector<int> > permuteUnique(vector<int> &num) {
        vector<vector<int>> result;
        
        std::sort(num.begin(), num.end());
        
        permuteIterate(num, result);
        //permute(num, result, 0);
        
        return result;
    }
    
    void permuteIterate(vector<int>& num, vector<vector<int>>& result)
    {
        std::sort(num.begin(), num.end());
        
        int n = num.size();
        
        while (1)
        {
            result.push_back(num);
            
            int i = n-2;
            while (i >= 0)
            {
                // find last pair that num[i] > num[i-1]
                
                if (num[i+1] > num[i])
                    break;
                
                i--;
            }
            
            if (i < 0)
                break;
                
            // swap num[i] with least great number
            
            int j = n-1;
            for (; j > i; j--)
            {
                if (num[j] > num[i])
                    break;
            }
            
            // swap num[i] and num[j]
            swap(num, i, j);

            // reverse from num[i+1] to num[n-1]
            
            int pl = i+1;
            int pr = n-1;
            
            while (pl < pr)
            {
                swap(num, pl, pr);
                pl ++;
                pr --;
            }
        }
    }
    
    void permute(vector<int>& num, vector<vector<int>>& result, int index)
    {
        if (index == num.size()-1)
        {
            result.push_back(num);
            return;
        }
        
        
        set<int> visited;
        
        for (int i = index; i < num.size(); i++)
        {
            if (visited.find(num[i]) != visited.end())
                continue;
                
            visited.insert(num[i]);

            swap(num, index, i);
            permute(num, result, index+1);
            swap(num, index, i);
        }
    }
    
    void swap(vector<int>& num, int i, int j)
    {
        if (i == j)
            return;
            
        int temp = num[i];
        num[i] = num[j];
        num[j] = temp;
    }    
};

 

posted @ 2015-03-26 13:48  smileheart  阅读(182)  评论(0)    收藏  举报