棋子

导航

Next Permutation

原题地址:https://leetcode.com/submissions/detail/48922153/ 

 

所谓一个排列的下一个排列的意思就是 这一个排列与下一个排列之间没有其他的排列。这就要求这一个排列与下一个排列有尽可能长的共同前缀,也即变化限制在尽可能短的后缀上。这句话的意思我一直没弄明白!

 
对于数字序列:
        
        先看前面2排的话,可以看出来第二排是比第一排要大的,参考字符串比较大小的问题。那么第2个排列是不是第一个排列的下一个排列呢。很明显不是,第3个排列才是, 那么如何获取到下一个排列呢。步骤比较简单:假设数组大小为 n
        1.从后往前,找到第一个 A[i-1] < A[i]的。也就是第一个排列中的  6那个位置,可以看到A[i]到A[n-1]这些都是单调递减序列。
        2.从 A[n-1]到A[i]中找到一个比A[i-1]大的值(也就是说在A[n-1]到A[i]的值中找到比A[i-1]大的集合中的最小的一个值)
        3.交换 这两个值,并且把A[n-1]到A[i]排序,从小到大。

 

 

 

 

 

 

Well, in fact the problem of next permutation has been studied long ago. From the Wikipedia page, in the 14th century, a man named Narayana Pandita gives the following classic and yet quite simple algorithm (with minor modifications in notations to fit the problem statement):

  1. Find the largest index k such that nums[k] < nums[k + 1]. If no such index exists, the permutation is sorted in descending order, just reverse it to ascending order and we are done. For example, the next permutation of [3, 2, 1] is [1, 2, 3].
  2. Find the largest index l greater than k such that nums[k] < nums[l].
  3. Swap the value of nums[k] with that of nums[l].
  4. Reverse the sequence from nums[k + 1] up to and including the final elementnums[nums.size() - 1].

Quite simple, yeah? Now comes the following code, which is barely a translation.这就是上面图片的另外一种表述!!

 

就看第一个算法就好了:

 1 class Solution {
 2 public:
 3     void nextPermutation(vector<int>& nums) //注意,这里传进来的可是引用
 4     {
 5         int index1,index2;
 6         for(int i=nums.size()-1;i>=0;i--)
 7         {
 8             if(i>=1 && nums[i-1]<nums[i])
 9             {
10                 index1=i-1;
11                 break;
12             }
13             if(i==0)
14             {
15                 reverse(nums,0,nums.size()-1);
16                 return;
17             }
18         }
19         for(int j=nums.size()-1;j>=0;j--)
20         {
21             if(nums[j]>nums[index1])
22             {
23                 index2=j;
24                 break;
25             }
26         }
27         int temp=nums[index1];
28         nums[index1]=nums[index2];
29         nums[index2]=temp;
30         reverse(nums,index1+1,nums.size()-1);
31     }
32     void reverse(vector<int>&nums,int begin,int end)
33     {
34         while(begin<end)
35         {
36             int temp=nums[begin];
37             nums[begin]=nums[end];
38             nums[end]=temp;
39             begin++;
40             end--;
41         }
42     }
43 };

 

 
#include<iostream>
#include<string>
#include<vector>
using namespace std;

class Solution {
public:
    void nextPermutation(vector<int>& nums) 
    {
        int index1,index2;
        for(int i=nums.size()-1;i>=0;i--)
        {
            if(i>=1 && nums[i-1]<nums[i])
            {
                index1=i-1;
                break;
            }
            if(i==0)
            {
                reverse(nums,0,nums.size()-1);
                return;
            }
        }
        for(int j=nums.size()-1;j>=0;j--)
        {
            if(nums[j]>nums[index1])
            {
                index2=j;
                break;
            }
        }
        int temp=nums[index1];
        nums[index1]=nums[index2];
        nums[index2]=temp;
        reverse(nums,index1+1,nums.size()-1);
    }
    void reverse(vector<int>&nums,int begin,int end)
    {
        while(begin<end)
        {
            int temp=nums[begin];
            nums[begin]=nums[end];
            nums[end]=temp;
            begin++;
            end--;
        }
    }
};

int main()
{
    Solution test;
    vector<int> arr;
    arr.push_back(1);
    arr.push_back(3);
    arr.push_back(2);
    for(int i=0;i<arr.size();i++)
        cout<<arr[i]<<endl;
    cout<<"after:"<<endl;
    test.nextPermutation(arr);
    for(int i=0;i<arr.size();i++)
        cout<<arr[i]<<endl;
}

 

posted on 2015-12-26 13:45  鼬与轮回  阅读(259)  评论(0编辑  收藏  举报