Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >LeetCode-31-下一个排列

LeetCode-31-下一个排列

作者头像
benym
发布于 2022-07-14 08:25:00
发布于 2022-07-14 08:25:00
28800
举报
文章被收录于专栏:后端知识体系后端知识体系
运行总次数:0

# LeetCode-31-下一个排列

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

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

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

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

# 解题思路

思路出处 (opens new window)

推导:

如何得到这样的排列顺序?这是本文的重点。我们可以这样来分析:

  1. 我们希望下一个数比当前数大,这样才满足“下一个排列”的定义。因此只需要将后面的「大数」与前面的「小数」交换,就能得到一个更大的数。比如 123456,将 5 和 6 交换就能得到一个更大的数 123465。
  2. 我们还希望下一个数增加的幅度尽可能的小,这样才满足“下一个排列与当前排列紧邻“的要求。为了满足这个要求,我们需要:
    1. 在尽可能靠右的低位进行交换,需要从后向前查找
    2. 将一个 尽可能小的「大数」 与前面的「小数」交换。比如 123465,下一个排列应该把 5 和 4 交换而不是把 6 和 4 交换
    3. 将「大数」换到前面后,需要将「大数」后面的所有数重置为升序,升序排列就是最小的排列。以 123465 为例:首先按照上一步,交换 5 和 4,得到 123564;然后需要将 5 之后的数重置为升序,得到 123546。显然 123546 比 123564 更小,123546 就是 123465 的下一个排列 以上就是求“下一个排列”的分析过程。

算法流程:

标准的“下一个排列”算法可以描述为:

  1. 从后向前查找第一个相邻升序的元素对 (i,j),满足 A[i] < A[j]。此时 [j,end) 必然是降序
  2. 在 [j,end) 从后向前查找第一个满足 A[i] < A[k] 的 k。A[i]、A[k] 分别就是上文所说的「小数」、「大数」
  3. 将 A[i] 与 A[k] 交换
  4. 可以断定这时 [j,end) 必然是降序,逆置 [j,end),使其升序
  5. 如果在步骤 1 找不到符合的相邻元素对,说明当前 [begin,end) 为一个降序顺序,则直接跳到步骤 4

# Java代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
    public void nextPermutation(int[] nums) {
        int len = nums.length;
        if (len < 2) return;
        int i = len - 2;
        int j = len - 1;
        int k = len - 1;
        // 从后向前找第一个正序,这里最后i指向的是逆序起始位置
        while (i >= 0 && nums[i] >= nums[j]) {
            i--;
            j--;
        }
        if (i >= 0) {
            // 从后向前找第一个比nums[j]大的元素,进行交换
            while (nums[i] >= nums[k]) {
                k--;
            }
            swap(nums, i, k);
        }
        // 翻转交换点后的数组,使后面的数组升序,保证整个数组是下一个最大数组
        reverse(nums, j, len - 1);
    }

    public void swap(int[] nums, int i, int j) {
        int temp = nums[j];
        nums[j] = nums[i];
        nums[i] = temp;
    }

    public void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[end];
            nums[end] = nums[start];
            nums[start] = temp;
            start++;
            end--;
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-07-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Leetcode No.31 下一个排列
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
week
2022/01/07
3110
☆打卡算法☆LeetCode 31、下一个排列 算法解析
“将数组序列重新排列成下一个更大的排列,如果不存在下一个更大的排列,则将数组排列成最小的排列。”
恬静的小魔龙
2022/08/07
3310
☆打卡算法☆LeetCode 31、下一个排列  算法解析
LeetCode31. 下一个排列
思路:下一个排列”的定义是:给定数字序列的字典序中比原来大的里面最小的一个 //实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 // // 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 // // 必须 原地 修改,只允许使用额外常数空间。 // // // // 示例 1: // // //输入:nums = [1,2,3] //输出:[1,3,2] // // // 示例 2: // // //输入:nums = [3,2,1] /
周杰伦本人
2022/10/25
2230
LeetCode题目31:下一个排列
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
二环宇少
2020/08/13
4410
LeetCode题目31:下一个排列
​LeetCode刷题实战31:下一个排列
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
程序员小猿
2021/01/20
3730
LeetCode-31 下一个排列
今天我们学习第31题下一个排列,这是一个中等的数组题。我们先看看这道题的题目描述。
用户3470542
2019/06/26
6650
LeetCode-31 下一个排列
【刷穿 LeetCode】31. 下一个排列(中等)
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
宫水三叶的刷题日记
2021/02/20
3420
下一个排列(leetcode31)
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
Vincent-yuan
2021/04/09
2930
31. 下一个排列
思路: 我们希望找到一种方法,能够找到一个大于当前序列的新序列,且变大的幅度尽可能小。 我们需要将一个左边的「较小数」与一个右边的「较大数」交换,以能够让当前排列变大,从而得到下一个排列。同时我们要让这个「较小数」尽量靠右,而「较大数」尽可能小。 当交换完成后,「较大数」右边的数需要按照升序重新排列。这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。 对于上面的第二句其实就是交换了以后使得我们被提前的那个数字后面的各位数字都是升序,这样后面的排列就是最小的,而且按照我们第一个步骤的筛选,我
名字是乱打的
2021/12/23
3200
31. 下一个排列
LeetCode 31. 下一个排列(线性扫描)
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
Michael阿明
2020/07/13
3760
LeetCode-下一个排列
感觉从之前的题目开始写起来的话,会需要一定的时间去思考当时为什么这么写,那么每次写都是重新思考,除非进度能够赶上最新的刷题进度,所以决定从最新的开始往前写....最近又一直在刷LeetCode中文官网的题目,毕竟英语题目理解能力捉鸡。
晓痴
2019/07/24
5430
LeetCode-下一个排列
2022-01-07:下一个排列。实现获取 下一个排列 的函数,算
2022-01-07:下一个排列。实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列(即,组合出下一个更大的整数)。
福大大架构师每日一题
2022/01/07
4240
leetcode-31-下一个排列
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
chenjx85
2018/08/16
1.1K0
打卡群刷题总结0628——下一个排列
链接:https://leetcode-cn.com/problems/next-permutation
木又AI帮
2020/07/02
3650
【leetcode刷题】20T17-下一个排列
https://leetcode-cn.com/problems/next-permutation/
木又AI帮
2020/02/19
3490
【一天一大 lee】下一个排列 (难度:中等) - Day20201110
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
前端小书童
2020/11/19
4830
【一天一大 lee】下一个排列 (难度:中等) - Day20201110
【每日一题】31. Next Permutation
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
公众号-不为谁写的歌
2020/08/04
3900
[Leetcode][python]Next Permutation/下一个排列
版权声明:本文为博主原创文章,转载请注明原文地址链接。 https://blog.csdn.net/qqxx6661/article/details/77876431
蛮三刀酱
2019/03/26
7790
Leetcode|从后向前找首对升序对再交换右侧数并升序|31. 下一个排列
其中nums[left] = 5,即left = 4 然后找到left右侧最小的比5大的数的索引,即nums[right] = 6, right = 6
SL_World
2022/01/10
2960
Leetcode|从后向前找首对升序对再交换右侧数并升序|31. 下一个排列
【力扣刷题】31. 下一个排列
例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。
jayjay
2022/11/02
5240
【力扣刷题】31. 下一个排列
相关推荐
Leetcode No.31 下一个排列
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档