LeetCode 题解(4):Next Permutation

题目:

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place, do not allocate extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,31,3,2
3,2,11,2,3
1,1,51,5,1

将当前permutation看作是一个整数,如将“1,2,3”看作123,则next permutation是由“1,2,3”所组成的最小的比“123”大的数,即“132”。如果当前permutation已为最大数,如"321",则其next permutation为起始的最小数,即"123"。


题解:

<span style="color:#000000;">class Solution {
public:
    void nextPermutation(vector<int> &num) {
        if(num.size() <= 1)
            return;
            
        vector<int>::iterator i = num.end();
        i = i - 2;
        while(true)
        {
            vector<int>::iterator j = i + 1;
            if(*i < *j)
            {
                vector<int>::iterator k = num.end();
                while(!(*i < *--k));
                
                iter_swap(i, k);
                reverse(j, num.end());
                return;
            }
            if( i == num.begin() )
            {
                reverse(num.begin(), num.end());
                return;
            }
            i--;
        }
    }
};</span>

测试用例:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(int argc, char* argv[])
{
    Solution s;
    int iArray[] = {1,2};
    size_t count = sizeof(iArray)/sizeof(int);
    vector<int> test(iArray, iArray+count);
    s.nextPermutation(test);
    return 0;
}

一年后再做。思路:规律是,从后往前找第一个升序对,如果升序对不存在,说明当前为最大值,rotate整个permutation后得到最小值。否则,存在升序对,则将升序对中小的数与 再次从后往前找的第一个比该数大的数交换,交换后将该数后的partial permutation做rotation。

自己造轮子的做法:

class Solution {
public:
    void nextPermutation(vector<int> &num) {
        if(!num.size())
            return;
        
        int i = num.size()-2;
        while(i >= 0) {
            if(num[i] < num[i+1])
                break;
            i--;
        }
        
        if(i < 0) {
            rotate(num, 0, num.size()-1);
        } else {
            int k = num.size()-1;
            while(k > i) {
                if(num[k] > num[i]) {
                    int temp = num[i];
                    num[i] = num[k];
                    num[k] = temp;
                    break;
                }
                k--;
            }
            rotate(num, i+1, num.size()-1);
        }
    }
    
    void rotate(vector<int> &num, int start, int end) {
        while(start <= end) {
            int temp = num[start];
            num[start] = num[end];
            num[end] = temp;
            start++;end--;
        }
    }
};

参考一年前的做法,使用STL函数简化代码:

class Solution {
public:
    void nextPermutation(vector<int> &num) {
        if(!num.size())
            return;
            
        auto i = num.end() - 2;
        while(i >= num.begin())
        {
            auto j = i + 1;
            if(*i < *j)
            {
                auto k = num.end()-1;
                while(*k <= *i) 
                    k--;

                iter_swap(i, k);
                reverse(j, num.end());
                return;
            }
            i--;
        }
        reverse(num.begin(), num.end());
    }
};

Java版:

public class Solution {
    public void nextPermutation(int[] num) {
        if(num.length <= 1)
            return;
        int i = num.length - 2;
        
        while(i >= 0) {
            if(num[i] < num[i+1])
                break;
            i--;
        }
        
        if( i >= 0 ) {
            int j = num.length - 1;
            while(num[j] <= num[i])
                j--;
            int temp = num[i];
            num[i] = num[j];
            num[j] = temp;
            rotate(num, i+1, num.length-1);
            return;
        }
        rotate(num, 0, num.length-1);
    }
    
    public void rotate(int[] num, int start, int end) {
        while(start <= end) {
            int temp = num[start];
            num[start] = num[end];
            num[end] = temp;
            start++;end--;
        }
    }
}

python版:

class Solution:
    # @param num, a list of integer
    # @return a list of integer
    def nextPermutation(self, num):
        if len(num) <= 1:
            return num
        
        i = len(num) - 2
        while i >= 0:
            if num[i] < num[i+1]:
                break
            i -= 1
            
        if i >= 0:
            j = len(num) - 1
            while num[j] <= num[i]:
                j -= 1
            temp = num[j]
            num[j] = num[i]
            num[i] = temp
            self.rotate(num, i+1, len(num)-1)
            return num
        
        self.rotate(num, 0, len(num)-1)
        return num
        
    def rotate(self, num, start, end):
        while start <= end:
            temp = num[start]
            num[start] = num[end]
            num[end] = temp
            start += 1
            end -= 1


你可能感兴趣的:(Algorithm,LeetCode)