每日一题——下一个排列

下一个排列

题目链接

在这里插入图片描述


读懂题目

要理解题目的意思,主要是要读懂这一句:整数数组的 下一个排列 是指其整数下一个字典序更大的排列

我们来逐词分析:

  • 其整数,即我们要将这个数组的数字构成一个十进制整数,例如数组[1,2,3]看成数字就是123,数组[4,0,3,2,1]看成数字就是40321
  • 下一个字典序更大:即我们要通过改变数组中的元素位置,从而使组成的整数大于原来的整数,并且变化幅度尽可能小。例如数组[1,2,3]的下一个排列就是[1,3,2](132大于123,且相较于由1,2,3组成的更大的数字变化幅度最小)

还有一个例外情况:如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)

  • 例如数组[3,2,1],构成的整数321已经是这三个数据所能构成的最大整数,因此它的下一个排列就是这三个数字的升序排列[1,2,3]

思路

我们以数组[4,5,2,6,3,1]为例,来讨论如何找到它的下一个排列:

  • 首先我们应该清楚,下标越小的数字,组成数据时位数越高,因此寻找下一个排列时尽量不要动前面的数字,即应该从低位数据开始考虑

在这里插入图片描述

  • 我们看到,后面的数字631已经是逆序排序,即[6,3,1]这三个数字组成的最大数字,因此我们不能仅仅通过改变这三个数的位置来找到下一个排列

  • 因此我们要继续向前看:到了数字2,我们发现**[2,6,3,1]不是逆序排序了**,即我们可以通过改变[2,6,3,1]这四个数的位置来找到到下一个排列,即次大数。那么具体的,该怎么改变才能保证改变后的数比之前的数大,并且变化幅度最小呢?
  • 由于[6,3,1]已经是降序排序,因此我们必须要增大更高位的数字2,而为了使变化幅度最小,我们应该将数字2, 3交换位置,并且使交换完后3后的数据为升序排序。

  • 最后,就得到了下一个排列[4,5,3,1,2,6]

总的来说就是:

我们需要将一个左边的较小数与一个右边较大数交换,以能够让当前排列变大,从而得到下一个排列。

同时我们要让这个较小数尽量靠右,而较大数尽可能小。当交换完成后,「较大数」右边的数需要按照升序重新排列。这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。

我们可以这样描述我们的算法:

  • 从后向前遍历数组元素,直到出现**nums[i] < nums[i+1]这样,较小数min就是nums[i]**
  • 从后往前遍历数组元素,直到出现**nums[j] > min,这样较大数max就是nums[j]**
  • 交换较小数min较大数max的位置,这样就得到了更大的数
  • 较大数max后的数据转换为升序排序,这样就可以使变化幅度最小,即得到下一个排列

注意:

  • 如果整个数组已经是降序排序,那么就不存在更大的数,难么他的下一个排列就是组成这个数组数据的升序排序. 而将降序转升序不需要采用时间复杂度较高的排序算法, 直接将整个数组反转即可, 时间复杂度为O(N)
  • 较大数较小数交换后, 将较大数后的数转为升序同理.

实现代码

//实现[left, right]区域数据的反转
void Reverse(int* nums, int left, int right)
{
    while (left <= right)
    {
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;

        left++;
        right--;
    }
}

//交换数据
void Swap(int *num1, int *num2)
{
    int temp = *num1;
    *num1 = *num2;
    *num2 = temp;
}

void nextPermutation(int* nums, int numsSize){
    //先找到 较小数
    int min;
    for (min = numsSize - 2; min >= 0; min--)
    {
        if (nums[min] < nums[min + 1])
            break;
    }
    
    //如果较小数不存在,那么直接将数组反转即可
    if (min < 0)
    {
        Reverse(nums, 0, numsSize - 1);
        return;
    }
	
    //找较大数
    int max;
    for (max = numsSize - 1; max > min; max--)
    {
        if (nums[max] > nums[min])
            break;
    }
	
    //交换较小数和较大数
    Swap(&nums[min], &nums[max]);
	
    //反转较大数后的数据
    Reverse(nums, min + 1, numsSize - 1);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/99915.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

并发编程的关键——LOCK

并发编程的关键——LOCK 锁的分类synchronized万物即可为锁synchronized的实现锁升级 LockAQSLockSupportCLHCAS Lock实现ReentrantLock阻塞方法acquireReadWriteLockReentrantReadWriteLockStampedLock 锁的分类 公平锁/非公平锁&#xff1a; – 公平的意思是多个线程按照申请…

解决vue项目首行报红( ESLint 配置)和新建的vue文件首行报红问题

目录 前情提要&#xff1a; 修改ESLint 配置 新建的vue文件首行还是报红 报红原因&#xff1a; 解决方法&#xff1a; 前情提要&#xff1a; 在网上查到的方法可能是在package.json文件或者.eslintrc.js文件中添加 requireConfigFile: false 如果此方法对你的错误不起作用…

2020ICPC南京站

K K Co-prime Permutation 题意&#xff1a;给定n和k&#xff0c;让你构造n的排列&#xff0c;满足gcd(pi, i)1的个数为k。 思路&#xff1a;因为x和x-1互质&#xff0c;1和任何数互质&#xff0c;任何数和它本身不互质 当k为奇数时&#xff0c;p11&#xff0c;后面k-1个数…

云原生Kubernetes:二进制部署K8S多Master架构(三)

目录 一、理论 1.K8S多Master架构 2.配置master02 3.master02 节点部署 4.负载均衡部署 二、实验 1.环境 2.配置master02 3.master02 节点部署 4.负载均衡部署 三、总结 一、理论 1.K8S多Master架构 (1) 架构 2.配置master02 &#xff08;1&#xff09;环境 关闭防…

yolov5自定义模型训练三

经过11个小时cpu训练完如下 在runs/train/expx里存放训练的结果&#xff0c; 测试是否可以检测ok 网上找的这张识别效果不是很好&#xff0c;通过加大训练次数和数据集的话精度可以提升。 训练后的权重也可以用视频源来识别&#xff0c; python detect.py --source 0 # webca…

盘点狼人杀中的强神与弱神 并评价操作体验

最初 强神是大家对猎人的称呼&#xff0c;但随着板子的增加 强神渐渐变成了强神神牌的统称。 狼人杀发展至今板子已经非常多了&#xff0c;而每个板子都会有不同的角色。 相同的是 大部分都会希望拿到一张强力神牌&#xff0c;这样能大大提高我们玩家的游戏体验&#xff0c;但其…

Vue2项目练手——通用后台管理项目第五节

Vue2项目练手——通用后台管理项目 首页组件布局面包屑&tag面包屑使用组件使用vuex存储面包屑数据src/store/tab.jssrc/components/CommonAside.vuesrc/components/CommonHeader.vue tag使用组件文件目录CommonTag.vueMain.vuetabs.js 用户管理页新增功能使用的组件页面布局…

Docker切换文件系统为VFS

一、介绍 Docker支持AUFS、Btrfs、Device Mapper、OverlayFS、VFS、ZFS六种不同的存储驱动。 1. AUFS AUFS是一种常见的存储驱动程序&#xff0c;它也使用了Linux内核的AUFS文件系统。它的优点是支持所有的Linux发行版&#xff0c;可以在不同的容器之间共享文件系统&#xf…

多因素认证与身份验证:分析不同类型的多因素认证方法,介绍如何在访问控制中使用身份验证以增强安全性

随着数字化时代的到来&#xff0c;信息安全问题变得愈发重要。在网络世界中&#xff0c;用户的身份往往是保护敏感数据和系统免受未经授权访问的第一道防线。单一的密码已经不再足够&#xff0c;多因素认证&#xff08;MFA&#xff09;应运而生&#xff0c;成为提升身份验证安全…

【RabbitMQ】RabbitMQ 服务无法启动。系统出错。发生系统错误 1067。进程意外终止。

问题描述 RabbitMQ 服务无法启动。 rabbitmq-service.bat startRabbitMQ 服务正在启动 . RabbitMQ 服务无法启动。系统出错。发生系统错误 1067。进程意外终止。原因分析 RabbitMQ和Erlang版本不匹配。 解决方案 查询并安装RabbitMQ版本对应Erlang版本 https://www.rabbitm…

解决window安装docker报错问题

第一次打开Docker Desktop后提示错误 试了网上版本都没用&#xff0c;后面发现是电脑没有下载相关虚拟机&#xff1a; 先点击链接下载wsl2&#xff0c;下载后命令行执行&#xff1a;dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /…

使用boost::geometry::union_ 合并边界(内、外):方案二

使用boost::geometry::union_ 合并边界&#xff08;内、外&#xff09;&#xff1a;方案二 typedef boost::geometry::model::d2::point_xy<double> boost_point; typedef boost::geometry::model::polygon<boost_point> boost_Polygon;struct Point {float x;floa…

ARM DIY(六)音频调试

前言 今天&#xff0c;调试一下音频 硬件焊接 硬件部分核心是 LM4871 音频功放芯片 对于 SOC 来讲很简单&#xff0c;就一个引脚 HPOUTL&#xff08;单声道&#xff09;&#xff1b;对于扬声器来讲也很简单&#xff0c;就两个引脚&#xff0c;插上就可以了。 另外一个关键点…

【Cadence】Calculator计算sp的3dB带宽

【Cadence】Calculator计算sp的3dB带宽 1.计算最大增益2.cross函数3. 3dB带宽 下面演示如何在Cadence计算s参数&#xff08;如增益&#xff09;的3dB带宽 1.计算最大增益 ymax函数 2.cross函数 cross函数可以计算经过y轴给定值对应的x坐标 edge number选择1是经过的第一个点…

DEAP库文档教程三-----创建类型

本节将继续展示如何通过creator创建类型以及如何使用toolbox如何对复杂问题进行初始化。 Particle的初始化--粒子初始化 一个Particle是另一个特殊类型的个体&#xff0c;这是因为通常情况下它有一个速度&#xff0c;并且有一个最优的位置需要去记忆。这种类型个体的创建与通…

探索云原生容器编排技术:如Kubernetes如何为大数据处理和AI模型的自动化部署带来便利

文章目录 1. 弹性伸缩2. 容器化3. 自动化部署4. 存储管理5. 服务发现和负载均衡6. 监控和日志记录7. 多云支持8. 多版本管理9. 安全性和隔离10. 社区支持和生态系统 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点…

Windows右键添加用 VSCODE 打开

1.安装VSCODE时 安装时会有个选项来添加&#xff0c;如下&#xff1a; ①将“通过code 打开“操作添加到windows资源管理器文件上下文菜单 ②将“通过code 打开”操作添加到windows资源管理器目录上下文菜单 说明&#xff1a;①②勾选上&#xff0c;可以对文件&#xff0c;目…

【CicadaPlayer】getPlayerBufferDuration分析

https://github.com/alibaba/CicadaPlayer/blob/release/0.4.4/mediaPlayer/SuperMediaPlayer.cpp核心关键函数int64_t SuperMediaPlayer::getPlayerBufferDuration(bool gotMax, bool internal)17个地方出现: getPlayerBufferDuration的durations 数组 分别 对音频、视频、字…

企业供应链数字化怎么做?企业数字化供应链流程落地方式

什么是供应链&#xff1f;简单来说&#xff0c;供应链是围绕客户需求&#xff0c;以提高产品流通各个环节的效率为目标&#xff0c;通过资源整合的方式来实现产品从设计、生产到销售、服务整个环节的组织形态。如同人工智能、区块链、5G等技术的发展带来的各种行业变化&#xf…

嵌入式岗位笔试面试专栏 - 岗位介绍

文章目录 一、嵌入式岗位的分类二、热门领域及公司三、发展前景四、技能要求沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将讲解嵌入岗位的工作职责 。 一、嵌入式岗位的分类 嵌入式软件工程师大致可以分为两种类型: 应用开发工程师驱动开发工程师应用工程…
最新文章