下一个排列_题解

【题解提供者】史青山

解法

思路

此题属于找规律题,我们可以把一个序列的全排列写出来,然后对比找规律,比如序列 1 2 3 4 5,全排列如下:
1 2 3 4 5
1 2 3 5 4
1 2 4 3 5
1 2 4 5 3
1 2 5 3 4
1 2 5 4 3
1 3 2 4 5
1 3 2 5 4

我们观察 1 2 5 4 3 -> 1 3 2 4 5 变化过程,发现从右往左遍历过程中,2 5 破坏了递增趋势,然后对右边序列从右往左遍历找到第一个大于 2 的元素 3,然后将 2 和 3 交换位置,右边剩下的序列 5 4 2 按照升序排列得到 2 4 5,最后得到的序列正好是下一个排列。

下面我们探讨一下,假设拿到这个题,根本不知道上面的解法,或者说根本不知道从找规律的角度去解题,那我们能不能尝试着从题目的本质去找寻解题的思路呢?我们分析这题,此题要求的是求下一个排列,一个最直观的想法是,我们可以先把序列的全排列求出来,然后在这个全排列中找到当前的这个序列,然后这个序列位置的下一个序列即为下一个排列,但是,代价是空间复杂度和时间复杂度都高。有没有其他思路呢?

排列的原则是一开始尽量将较大的值往后排,当较大的值在后半序列排完了后,再把它与前面恰好小于它的数交换,然后后边序列全部升序,就能得到它的下一个排序。

也就是以下这三点:

  • 在尽可能靠右的低位进行交换,需要从后向前查找。

  • 将一个幅度变化小的「大数」 与前面的「小数」交换。
    PS:

    前两步保证了满足交换的俩个数一定是升序。
    如 1 6 5 4 3 2 我们就找 1 和 2 让它们进行交换,但是只交换 2 和 1 也不行,因此有了下面这一点。

  • 将「大数」换到前面后,需要将「大数」后面的所有数重置为升序,因为升序排列就是字典序最小的排列。
    那么后面的数一定是降序,我们需要把他们变成升序,满足了增加幅度但是不那么大满足“下一个排列”。如 1 6 5 4 3 2 的下一个排列是 2 1 3 4 5 6 ,1 2 3 4 6 5 的下一个排列是 1 2 3 5 4 6 。

代码展示

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;
vector<int> a;int main() {int n, x;cin >> n;for (int i = 0; i < n; i++) {cin >> x;a.push_back(x);}int pos = n - 2;//用pos来记录倒数第二个数的下标 从后向前找while (pos >= 0 && a[pos] >= a[pos + 1]) pos--;if (pos >= 0) {int j = n - 1;//找出nums[pos]后面大于nums[pos]的最小数的下标while (a[j] <= a[pos]) j--;swap(a[pos], a[j]);reverse(a.begin() + pos + 1, a.end());//交换完后对nums[pos]后面的数字进行从小到大排列//因为此时nums.begin()+pos+1到nums.end()一定是降序排列,所以只需reverse就是从小到大排列了} else {//说明是最大排列,下一个应该是最小排列reverse(a.begin(), a.end());}for (int i = 0; i < n; i++) cout << a[i] << " ";return 0;
}

算法分析

本程序的时间复杂度为 O ( n ) O(n) O(n)

拓展

本题可以使用 <algorithm>中库函数 next_permutation完成题中所需功能。

代码展示
#include <iostream>
#include <algorithm>
using namespace std;const int N = 109;
int a[N];int main() {int n;  cin >> n;for(int i = 0; i < n; i ++) cin >> a[i];next_permutation(a, a + n);for(int i = 0; i < n; i ++) cout << a[i] << ' ';return 0;
}

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

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

相关文章

ssh使用密钥远程连接问题排查

ssh使用密钥远程连接时&#xff0c;会因为各项原因导致无法连接 本文以本机(windows), 连接目标机(Ubuntu) 为例&#xff0c; 列出应该逐项排查的问题&#xff0c; 确保能够正确连接 1. 确保两机器能够相互ping通 windows和linux都有防火墙&#xff0c; 双方ping不同大概率是因…

7、7 个适合初学者的项目,让您开始使用 ChatGPT

7 个适合初学者的项目,让您开始使用 ChatGPT 在当今世界释放人工智能的力量。 在技术以前所未有的速度发展的时代,人工智能?—?或朋友🤓的人工智能脱颖而出,成为最具变革性的力量之一。 从自动化日常任务到预测复杂模式,人工智能正在重塑行业并重新定义可能性。 当我…

Unity2D 学习笔记 0.Unity需要记住的常用知识

Unity2D 学习笔记 0.Unity需要记住的常用知识 前言调整Project SettingTilemap相关&#xff08;创建地图块&#xff09;C#脚本相关程序运行函数private void Awake()void Start()void Update() Collider2D碰撞检测private void OnTriggerStay2D(Collider2D player)private void…

【Algorithms 4】算法(第4版)学习笔记 06 - 2.3 快速排序

文章目录 前言参考目录学习笔记1&#xff1a;基本算法1.1&#xff1a;快速排序 demo 演示1.2&#xff1a;快速排序切分代码实现1.3&#xff1a;实现细节1.4&#xff1a;案例分析1.4.1&#xff1a;最佳案例1.4.2&#xff1a;最坏案例1.4.3&#xff1a;平均案例分析1.5&#xff1…

【MySQL】学习和总结DCL的权限控制

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-Bl9kYeLf8GfpdQgL {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

消息队列MQ 介绍

&#x1f47d;System.out.println(“&#x1f44b;&#x1f3fc;嗨&#xff0c;大家好&#xff0c;我是代码不会敲的小符&#xff0c;双非大四&#xff0c;Java实习中…”); &#x1f4da;System.out.println(“&#x1f388;如果文章中有错误的地方&#xff0c;恳请大家指正&a…

Vue-56、Vue技术路由的使用

路由 1、理解&#xff1a;一个路由&#xff08;route&#xff09;就是一种映射关系&#xff08;key-value&#xff09;&#xff0c;多个路由需要路由器&#xff08;router&#xff09;进行管理。 2、前端路由&#xff1a;key是路径&#xff0c;value是组件 1、基本使用 vue…

JFinal中如何实现反序列化----JSON字符串向Model对象转换

需求: 将客户端传来的requestbody反序列化成对应的Model对象。 一、反序列化--驼峰命名 1、fastjson实现 JFinal中没有提供反序列化的方法&#xff0c;因为大多数情况下&#xff0c;可以直接通过jar包进行转换&#xff0c;如利用fastjson&#xff0c;我们可以通过如下方式进行…

Renitialized existing Git repositoy in D:/libai/project/gitab-cicd-test/.git/

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

vue 引入 百度地图API 和 路书

公司项目中&#xff0c;偶尔都会涉及到地图的使用&#xff0c;这里以百度地图为例&#xff0c;我们梳理一下引用流程及注意点 账号和获取密钥 百度地图示例 百度地图 类参考 1、账号和获取密钥 // api.map.baidu.com/api?typewebgl&v3.0&ak您的密钥<script type…

1899_野火FreeRTOS教程阅读笔记_任务创建

1899_野火FreeRTOS教程阅读笔记_任务创建 全部学习汇总&#xff1a; g_FreeRTOS: FreeRTOS学习笔记 (gitee.com) 关于这部分&#xff0c;从一般前后台程序到RTOS的任务描述了很多。但是我觉得这本书的这部分描述没有描述到关键的信息点。其实&#xff0c;RTOS存在的一个主要的目…

机器学习系列——(十七)聚类

引言 在当今数据驱动的时代&#xff0c;机器学习已经成为了解锁数据潜能的关键技术之一。其中&#xff0c;聚类作为机器学习领域的一个重要分支&#xff0c;广泛应用于数据挖掘、模式识别、图像分析等多个领域。本文旨在深入探讨聚类技术的原理、类型及其应用&#xff0c;为读…

【Flink入门修炼】1-3 Flink WordCount 入门实现

本篇文章将带大家运行 Flink 最简单的程序 WordCount。先实践后理论&#xff0c;对其基本输入输出、编程代码有初步了解&#xff0c;后续篇章再对 Flink 的各种概念和架构进行介绍。 下面将从创建项目开始&#xff0c;介绍如何创建出一个 Flink 项目&#xff1b;然后从 DataStr…

IDEA创建Java类时自动添加注释(作者、年份、月份)

目录 IDEA创建Java类时自动添加注释&#xff08;作者、年份、月份&#xff09;如图&#xff1a; IDEA创建Java类时自动添加注释&#xff08;作者、年份、月份&#xff09; 简单记录下&#xff0c;IDEA创建Java类时自动添加注释&#xff08;作者、年份、月份&#xff09;&#…

Java+微信小程序实现智慧家政系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询家政服务4.2 新增单条服务订单4.3 新增留言反馈4.4 小程序登录4.5 小程序数据展示 五、免责说明 一、摘要 1.1 项目介绍 基于微信小程序JAVAVueSpringBootMySQL的智慧家政系统&#xff0…

【SparkML实践7】特征选择器FeatureSelector

本节介绍了用于处理特征的算法&#xff0c;大致可以分为以下几组&#xff1a; 提取&#xff08;Extraction&#xff09;&#xff1a;从“原始”数据中提取特征。转换&#xff08;Transformation&#xff09;&#xff1a;缩放、转换或修改特征。选择&#xff08;Selection&…

作业2.8

1、选择题 1.1、以下选项中,不能作为合法常量的是 ____B______ A&#xff09;1.234e04 B&#xff09;1.234e0.4 C&#xff09;1.234e4 D&#xff09;1.234e0 1.2、以下定义变量并初始化错误的是_____D________。 A) char c1 ‘H’ &#xff1b; B) char c…

RabbitMQ高可用架构涉及常用功能整理

RabbitMQ高可用架构涉及常用功能整理 1. rabbitmq的集群模式2. 镜像模式高可用系统架构和相关组件3. rabbitmq的核心参数3.1 镜像策略3.2 新镜像同步策略3.3 从节点晋升策略3.4 主队列选择策略 4. rabbitmq常用命令4.1 常用基础命令4.1.1 服务管理4.1.2 用户管理4.1.3 角色管理…

数字图像处理(实践篇)四十七 OpenCV-Python 高动态范围HDR

目录 一 HDR 二 实践 高质量的图像具备的要素如下: ①分辨率 图像中的像素数量。在特定屏幕尺寸下,分辨率越高,像素越多,显示的细节更精细。 ②位深度

JavaEE作业-实验三

目录 1 实验内容 2 实验要求 3 思路 4 核心代码 5 实验结果 1 实验内容 简单的线上图书交易系统的web层 2 实验要求 ①采用SpringMVC框架&#xff0c;采用REST风格 ②要求具有如下功能&#xff1a;商品分类、订单、购物车、库存 ③独立完成&#xff0c;编写实验报告 …