每日一题——下一个排列

下一个排列

题目链接

在这里插入图片描述


读懂题目

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

我们来逐词分析:

  • 其整数,即我们要将这个数组的数字构成一个十进制整数,例如数组[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.hqwc.cn/news/98949.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt中布局管理使用总结

目录 1. 五大布局 1.1 QVBoxLayout垂直布局 1.2 QHBoxLayout水平布局 1.3 QGridLayout网格布局 1.4 QFormLayout表单布局 1.5 QStackedLayout分组布局 1.6 五大布局综合应用 2. 分割窗口 3. 滚动区域 4. 停靠区域 1. 五大布局 1.1 QVBoxLayout垂直布局 #include <…

软件测试/测试开发丨Web自动化测试 关键数据记录

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/27105 记录关键数据的作用 内容作用日志1、记录代码执行情况&#xff0c;方便复现场景&#xff0c;也可以作为bug依据截图1、断言失败或成功的截图&#…

Yapi接口一键生成Java代码

Yapi上定义好接口之后,转换成Java代码时费时费力,都是重复劳动,毫无意义,所以有了这个工具把程序员从大量重复劳动中解放出来。 1:修改application.properties yapi.project.token=f1a0ea09031f41e1adfa18a 获取方法如下: yapi.api.interface.ids和yapi.api.cat.id只配置…

QT实现TCP通信(服务器与客户端搭建)

一、TCP通信框架 二、QT中的服务器操作 创建一个QTcpServer类对象&#xff0c;该类对象就是一个服务器调用listen函数将该对象设置为被动监听状态&#xff0c;监听时&#xff0c;可以监听指定的ip地址&#xff0c;也可以监听所有主机地址&#xff0c;可以通过指定端口号&#x…

mysql trace

optimizer_trace 它可以跟踪优化器做出的各种决策&#xff08;比如访问表的方法、各种开销计算、各种转换等&#xff09;&#xff0c;并将跟踪结果记录到 information_schema 数据库中的 optimizer_trace 表中。 mysql 默认是关闭 追踪的 开启、并设置格式为 josn,同时设置trac…

unity 之参数类型之引用类型

文章目录 引用类型引用类型与值类型的差异 引用类型 在Unity中&#xff0c;引用类型是指那些在内存中存储对象引用的数据类型。以下是在Unity中常见的引用类型的介绍&#xff1a; 节点&#xff08;GameObject&#xff09;&#xff1a; 在Unity中&#xff0c;游戏对象&#xff…

手写Mybatis:第20章-Mybatis 框架源码10种设计模式分析

文章目录 一、类型&#xff1a;创建型模式1.1 工厂模式1.2 单例模式1.3 建造者模式 二、类型&#xff1a;结构型模式2.1 适配器模式2.2 代理模式2.3 组合模式2.4 装饰器模式 三、类型&#xff1a;行为型模式3.1 模板模式3.2 策略模式3.3 迭代器模式 一、类型&#xff1a;创建型…

机器学习算法详解1:基础知识合集

机器学习算法详解1&#xff1a;基础知识合集 前言 ​ 本系列主要对机器学习上算法的原理进行解读&#xff0c;给大家分享一下我的观点和总结。 本篇前言 ​ 开一个新系列&#xff0c;另外现在开学了&#xff0c;忙起来了&#xff0c;所以更新会很慢。 目录结构 文章目录 机器学…

RS-485/RS-422收发器电路 DP3085 国产低成本替代MAX3085

DP3085是5V、半双工、15kV ESD 保护的 RS-485/RS-422 收发器电路&#xff0c;电路内部包含一路驱动器和一路接收器。 DP3085具有增强的摆率限制&#xff0c;助于降低输出 EMI 以及不匹配的终端连接引起的反射&#xff0c;实现 500kbps 的无误码数据传输。 DP3085芯片接收器输入…

使用Puppeteer进行游戏数据可视化

导语 Puppeteer是一个基于Node.js的库&#xff0c;可以用来控制Chrome或Chromium浏览器&#xff0c;实现网页操作、截图、测试、爬虫等功能。本文将介绍如何使用Puppeteer进行游戏数据的爬取和可视化&#xff0c;以《英雄联盟》为例。 概述 《英雄联盟》是一款由Riot Games开…

uni-app 之 图片

uni-app 之 图片 获取图片 v-bind 动态绑定 image.png <template><view><view>--- 获取图片1 ---<image src"../../static/img/tabbar_home1.png"></image></view><view>--- 获取图片2 v-bind 动态绑定---<image v-bi…

实现Android APK瘦身99.99%

摘要&#xff1a; 如何瘦身是 APK 的重要优化技术。APK 在安装和更新时都需要经过网络下载到设备&#xff0c;APK 越小&#xff0c;用户体验越好。本文作者通过对 APK 内在机制的详细解析&#xff0c;给出了对 APK 各组成成分的优化方法及技术&#xff0c;并实现了一个基本 APK…