有关排列的题目,如果用DFS去做,就十分低效。这里介绍一种做法:求下一个序列,先从尾部开始找最长的递增数组,如果从尾到头都是递增,则这已经是最大序列,下一个序列就是将最大序列翻转一下。如果不存在递增数组,则将最后两位数交换一下。其他情况,则记录下递增数组的前一位数,并找出递增数组中比这个数大的最小的那个数,交换两个数位置,然后将这个递增数组翻转一下,结果就是下一个序列。网上可以找到相关证明。
1 class Solution { 2 public: 3 void nextPermutation(vector & nums) { 4 if(nums.size()<=1) 5 return; 6 int i=nums.size()-1; 7 while(i>=1&&nums[i-1]>=nums[i]) 8 { 9 i--;10 }11 if(i==0)12 {13 reverse(nums.begin(),nums.end());14 }15 else if(i==nums.size()-1)16 {17 swap(nums[i],nums[i-1]);18 }19 else20 {21 i--;22 int j;23 for(j=nums.size()-1;j>=i;j--)24 {25 if(nums[j]>nums[i])26 break;27 }28 swap(nums[i],nums[j]);29 reverse(nums.begin()+i+1,nums.end());30 }31 }32 };
如果要求上一个序列,则是找最长的递减数组。其他分析都差不多。
1 class Solution { 2 public: 3 void prevPermutation(vector & nums) { 4 if(nums.size()<=1) 5 return; 6 int i=nums.size()-1; 7 while(i>=1&&nums[i-1]<=nums[i]) 8 { 9 i--;10 }11 if(i==0)12 {13 reverse(nums.begin(),nums.end());14 }15 else if(i==nums.size()-1)16 {17 swap(nums[i],nums[i-1]);18 }19 else20 {21 i--;22 int j;23 for(j=nums.size()-1;j>=i;j--)24 {25 if(nums[j]