题目描述

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

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

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

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

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. Python-- easy_install 的安装

    http://peak.telecommunity.com/dist/ez_setup.py 将这里面的复制出来打包成ez_setup.py 然后cmd到目录下,直接输入ez_setup.py 可能会 ...

  2. C 内置函数

    *) strcat()用于连接两个字符串 *) 函数 memcpy() 用来复制内存到另一个位置.

  3. 剑指 Offer——13. 调整数组顺序使奇数位于偶数前面

    题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变.这和书本不太一样. 解 ...

  4. 最新整理的spring面试题从基础到高级,干货满满

    最新整理的spring面试题从基础到高级,干货满满 前言: 收藏了一些关于Spring的面试题,一方面是为了准备找工作的时候看面试题,另一方面,通过面试题的方式加深一些自己的理论知识. spring ...

  5. RV64I基础整数指令集

    RV64I是RV32I的超集,RV32I是RV64I的子集.RV64I包括RV32I的所有40条指令,另外增加了12条RV32I中没有的指令,还有三条移位指令(slli, srli,srai)也进行小 ...

  6. MES系统如何帮助烟草行业管理生产流程

    与很多其他行业一样,烟草MES系统可以帮助卷烟企业实现智能生产.精益制造.快速实现烟草企业数字化车间的创建,助力企业实现改造升级,从而提升企业生产效率,降低生产成产.烟草行业得MES者得天下. 烟草行 ...

  7. MVC的View本质和扩展

    一:网站启动流程简介 前面两节我们有介绍管道处理模型,然后下图总结出了mvc启动的整个流程 二:MVC返回的三种结果 从之前的流程已经反编译源码我们晓的,mvc最终都会返回一个结果,其中大概分为以下三 ...

  8. 201871010118-唐敬博《面向对象程序设计(java)》第十六周学习总结

    博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 <https://www.cnblogs.com/nwnu-daizh/> 这个作业的要求在哪里 <https://ww ...

  9. opencv鼠标事件

    #include <opencv2\opencv.hpp> using namespace cv; struct mouse_para { cv::Mat org; cv::Mat img ...

  10. LeetCode 113. Path Sum II路径总和 II (C++)

    题目: Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the give ...