【ATT】Next Permutation

Q:

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,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

A: 从右往左找到第一对逆序(a[i]<a[i+1]),那么a[i]是需要被替换的,那么用哪个值来替换呢?a[i+1]~a[n-1]是递减的,从里面找出大于a[i]的最小数a[j],两者互换;最后reverse a[i+1]~a[n-1]。如果找不到这样的逆序对,表示当前的序列是最大的,reverse a[0]~a[n-1]

 

类似的问题:给定一个正整数n,求比n大的最小整数k,使得k的二进制表示1的个数和n的二进制表示1的个数相等。

A:从表示n的二进制表示是a0a1...am,从低位开始查找第一个1的位置i,接着继续往高位查找第一个0的位置j,swap ai,aj,最后reverse ai+1~an-1;如果找不到i,j,说明找不到这样的k。

    void swap(int* a,int *b)
    {
        int tmp = *a;
        *a = *b;
        *b = tmp;
    }
    void reverse(int* l, int* r)
    {
        while(l<r)
        {
            swap(l,r);
            l++;
            r--;
        }
    }
    void nextPermutation(vector<int> &num) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if(num.empty())
            return;
            
        int i,j;
            
        for(i=num.size()-2;i>=0;i--)
        {
            if(num[i]<num[i+1]) 
            {
                for(j=i+1;j<num.size();j++)
                {
                    if(j==num.size()-1||num[j+1]<=num[i])
                    {
                        swap(&num[i],&num[j]);
                        reverse(&num[i+1],&num[num.size()-1]);
                        return;
                    }
                }
            }
        }
        
        reverse(&num[0],&num[num.size()-1]);
    }

  

 

posted @ 2013-09-19 16:59  summer_zhou  阅读(262)  评论(0编辑  收藏  举报