Next Permutation

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

 

所謂一個排列的下一個排列的意思就是 這一個排列與下一個排列之間沒有其餘的排列。這就要求這一個排列與下一個排列有儘量長的共同前綴,也即變化限制在儘量短的後綴上。這句話的意思我一直沒弄明白!算法

 
對於數字序列:
        
        先看前面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.這就是上面圖片的另一種表述!!ui

 

就看第一個算法就行了:spa

 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;
}
相關文章
相關標籤/搜索