题目描述

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

来源:力扣(LeetCode)

题解

输入的数组为nums[n-1],本题目的解题思路是,从j=n-2往前遍历,判断nums[j+1,n-1]中是否有一个元素刚刚大于nums[j]的元素,如果有的话则交换。为了减少比较次数,将nums[j+1,n-1]首先进行从小到大排序,并且可以保证交换之后的nums[j+1,n-1]也是是一个从小到大的排序序列,进而保证nums是“下一个更大的排列”。

因为本方法从从后往前遍历的,第一次排序发生在j=n-3,因为j=n-2时没发生交换,所以nums[n-2]必定大于nums[n-1]。此后的循环便依赖于上一次的排序结果,所以只需在每次循环时将nums[j+1,n-1]的nums[j+1]移动到最后一位(firstToLast()),便完成了排序

例:nums = 6,4,5,3,2

  • 当 j= 3 时,nums[j+1,n-1] = 2,不发生交换
  • 当 j= 2 时,nums[j+1,n-1] = 3,2,执行firstToLast(),nums[j+1,n-1] = 2,3
  • 当 j=1,时,nums[j+1,n-1] = 5,2,3, 执行firstToLast(),nums[j+1,n-1] = 2,3,5,此时发生交换,nums[j] = 5,nums[j+1,n-1] = 2,3,4
  • 输出 6,5,2,3,4

最终,

执行用时 :4 ms, 在所有 cpp 提交中击败了99.88%的用户

内存消耗 :8.5 MB, 在所有 cpp 提交中击败了94.92%的用户

C++代码

class Solution {
public:
void nextPermutation(vector<int>& nums) {
int i = nums.size()-2;
while(i >= 0){
firstToLast(i+1,nums);
for(int j = i+1; j < nums.size(); j++){
if(nums[j]>nums[i]){
swap(i,j,nums);
return;
}
}
i--;
}
firstToLast(0,nums);
}
void swap(int i,int j,vector<int>&nums){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
void firstToLast(int begin,vector<int>&nums){
int tmp = nums[begin];
for(int i=begin;i<nums.size()-1;i++){
nums[i] = nums[i+1];
}
nums[nums.size()-1] = tmp;
}
};

31,Leetcode下一个排列 - C++ 原地算法的更多相关文章

  1. 31、下一个排列 | 算法(leetode,附思维导图 + 全部解法)300题

    零 标题:算法(leetode,附思维导图 + 全部解法)300题之(31)下一个排列 一 题目描述 二 解法总览(思维导图) 三 全部解法 1 方案1 1)代码: // 方案1 "双指针法 ...

  2. 【LeetCode 31】下一个排列

    题目链接 [题解] 从右往左找第一个下降的位置i(即满足nums[i]<nums[i+1]); 然后在[i+1..len-1]这个区间里面找到一个最大的下标k,使得nums[k]>nums ...

  3. LeetCode:下一个排列【31】

    LeetCode:下一个排列[31] 题目描述 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排 ...

  4. Java实现 LeetCode 31下一个排列

    31. 下一个排列 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许 ...

  5. LeetCode 31. 下一个排列 | Python

    31. 下一个排列 题目 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改, ...

  6. LeetCode(31): 下一个排列

    Medium! 题目描述: (请仔细读题) 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列) ...

  7. Leetcode题库——31.下一个排列

    @author: ZZQ @software: PyCharm @file: nextPermutation.py @time: 2018/11/12 15:32 要求: 实现获取下一个排列的函数,算 ...

  8. [LeetCode] 31. Next Permutation 下一个排列

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  9. Leetcode题目31.下一个排列(中等)

    题目描述: 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外 ...

随机推荐

  1. Linux链接文件——管理链接文件的命令

    Linux链接文件——管理链接文件的命令 摘要:本文主要学习了在Linux系统中创建链接文件的命令. ln命令 ln命令用于给文件创建链接,是Link的缩写. 基本语法 ln [选项] 源文件 目标文 ...

  2. i春秋四周年福利趴丨一纸证书教你赢在起跑线

    i春秋四周年庆典狂欢已接近尾声 作为压轴福利 CISP-PTE认证和 CISAW-Web安全认证 迎来了史无前例的超低折扣 每个行业都有特定的精英证书,例如会计行业考取的是注册会计师证,建筑行业是一级 ...

  3. 别忘了在使用MES系统之前,还有关键一步!

    如果你是不熟悉工业自动化领域的专业人士,又或者是从IT或其他背景进入到操作技术(OT)领域的相关人士,那么我相信你不会后悔读到这篇文章. 我们都想做到智能化生产,想将MES系统,APS系统应用到生产过 ...

  4. vue -全局组件和局部组件

    1.全局组件:Vue.component('标签名', 构造器名) Vue.component('mycpn', cpnC) 注:这种注册组件的方式是全局组件,可以在多个Vue实例中使用. 2.局部组 ...

  5. Jenkins-Master-slave架构(八)

    一.增加slave节点 1.1 查看当前节点 系统管理-节点管理  1.2 新建节点  1.3 配置节点信息 可以选择只允许运行绑定到这台机器的job  1.4 保存后,使节点上线即可. 二.配置任务 ...

  6. jenkins部署报404错误

    环境:tomcat 7+jdk1.7+win10 64 jenkins_1.5.23 部署完成后服务器启动输入网址:http://192.168.3.100:8080/jenkins打开无法访问报40 ...

  7. shell之seq

    seq 用于生成从一个数到另一个数之间的所有整数 seq [选项]... 尾数 seq [选项]... 首数 尾数 seq [选项]... 首数 增量 尾数 例如: 1.  -s 指定分隔符,默认分隔 ...

  8. day33_8_15 并发编程4,线程池与协程,io模型

    一.线程池 线程池是一个处理线程任务的集合,他是可以接受一定量的线程任务,并创建线程,处理该任务,处理结束后不会立刻关闭池子,会继续等待提交的任务,也就是他们的进程/线程号不会改变. 当线程池中的任务 ...

  9. 网络yum源配置

    系统环境:CentOS7 [1] 首先备份/etc/yum.repos.d/CentOS-Base.repo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum ...

  10. WordCount-JAVA版

    WordCountMapper import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.apac ...