leetcode - 31. Next Permutation - Medium

descrition

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

解析

方法 1

暴力解决,O(n!) 的时间复杂度求出数组的全排列,然后返回比当前排列大的序列中最小的。

方法 2

时间复杂度:O(n);空间复杂度:O(1)

这里有很好的解释

不失一般性,假设数组如图所示。我们从后往前遍历数组,比较相邻的两个数,直到出现前一个数小于后一个数时,循环停止。如图中 a[i-1] < a[i],循环的结果有以下两点说明:

  • 在 a[i,...n-1] 是非递增有序(递减有序)的数组,因为 for 循环提前结束的条件是 a[i-1] < a[i],如果没有提前结束则说明,a[i-1] > a[i]。在这样的情况下,我们需要找到 a[i,...,n-1] 中比 a[i-1] 大的数中最小的那个,假设为 a[j]。将 a[j] 和 a[i-1] 交换,由数组的性质可得 a[i,...,n-1] 依然保持非递增(递减)有序,这时我们只需要将 a[i,...,n-1] 反转,即可得到下一个最小的排列。
  • 如果循环没有提前结束,则说明每一次比较都是 a[i-1] > a[i],说明整个数组非递增(递减)有序。在这样的情况下直接将数组反转即可得到最小的排列。

具体实现的逻辑参看代码。

code


#include <iostream>
#include <vector>
#include <algorithm> using namespace std; class Solution{
public:
void nextPermutation(vector<int>& nums) {
if(nums.empty())
return; int isplit = -1;
for(int i=nums.size()-1; i>0; i--){
if(nums[i-1] < nums[i]){
isplit = i-1;
break;
}
} // if isplit == -1, which indicate nums is in descending
// otherwhise, [isplit+1, n-1] is descending if(isplit == -1){
reverse(nums, 0, nums.size()-1);
}else{
// construct next permutation
// find the smallest one from the numbers which larger than nums[isplit]
int ismallest = nums.size()-1;
while(ismallest>isplit && nums[ismallest] <= nums[isplit])
ismallest--; // nums[ismallest] > nums[isplit] >= nums[ismallest+1, ... , n-1]
// and nums[isplit+1, ismallest-1] >= nums[ismallest] >= nums[ismallest+1,..,n-1]
swap(nums[isplit], nums[ismallest]); // nums[isplit+1, ... , n-1] still in descending
// so just reverse
reverse(nums, isplit+1, nums.size()-1);
}
} void reverse(vector<int>& nums, int ileft, int iright){
while(ileft < iright){
swap(nums[ileft], nums[iright]);
ileft++;
iright--;
}
}
}; int main()
{
return 0;
}

最新文章

  1. 做个简单的RSS订阅(ASP.NET Core),节省自己的时间
  2. html文本垂直居中对齐
  3. 用Python写一个简单的Web框架
  4. git clone error: RPC failed; result=22, HTTP code = 502
  5. Atiti &#160;qq空间破解(3)------------gui图形化通用cli执行器atiuse
  6. CPU寄存器
  7. spring 源代码地址
  8. Hadoop虽然强大,但不是万能的(CSDN)
  9. 20145220《Java程序设计》实验一实验报告
  10. Wicket Hello World Example
  11. UVa 11077 (循环分解 递推) Find the Permutations
  12. 在eclipse中部署发布web项目 和 更改eclipseweb项目发布的路径
  13. [转]SSL协议详解
  14. XLua基础
  15. chmod 没有x权限怎么办
  16. bbs项目实现点赞和评论的功能
  17. Linux下的crontab定时执行任务详解
  18. SharePoint Online 创建图片库
  19. git命令--git checkout 之 撤销提交到暂存区的更改
  20. NVMe on RHEL7

热门文章

  1. 重温CSS3
  2. javascript执行机制
  3. 作为新手 HTML5如何自学为好?
  4. Linux上安装和卸载mysql数据库 (一)
  5. SQL---约束---add constraint方法添加约束
  6. Spring框架——IOC依赖注入
  7. java八大基本数据类型
  8. 机器学习算法 - 最近邻规则分类KNN
  9. springmvc中对日期格式化的处理
  10. mysql主从复制笔记