1. 问题描述:

给你一个正整数的数组 A(其中的元素不一定完全不同),请你返回可在一次交换(交换两数字 A[i] 和 A[j] 的位置)后得到的、按字典序排列小于 A 的最大可能排列。如果无法这么操作,就请返回原数组。

示例 1:

输入:[3,2,1]
输出:[3,1,2]
解释:
交换 2 和 1

示例 2:

输入:[1,1,5]
输出:[1,1,5]
解释: 
这已经是最小排列

示例 3:

输入:[1,9,4,6,7]
输出:[1,7,4,6,9]
解释:
交换 9 和 7

示例 4:

输入:[3,1,1,3]
输出:[1,3,1,3]
解释:
交换 1 和 3

提示:

  1. 1 <= A.length <= 10000
  2. 1 <= A[i] <= 10000​​​​​​

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/previous-permutation-with-one-swap

2. 思路分析:

① 首先需要观察交换的数字的排列存在什么特点,可以发现交换的数字都是存在逆序的特点(大多是逆序的数字与最后一个位置交换)我们可以从数组A的最后一个位置往前找第一个不满足A[i] > A[i - 1]的位置i,所以对A数组逆序遍历找到第一个单调递增的位置,比如[1,9,4,6,7],从后往前找第一个不是单调递增的数字为4,这个时候我们找的i前一个位置的数字9就是一个可能需要交换的数字,上面的例子中数字9就可以与最后一个数字进行交换从而得到交换一次使得字典序排列比之前的排序小的最大可能排列(为什么是最后一个数字呢?因为我们是从数组A的最后一个位置开始往前找的,所以越往后面的数字是越大的所以需要交换i - 1位置与数组中的最后一个位置)

② 一开始的时候想到的①中的思路大体上是正确的,但是在某些细节上可能不对我们只需要对某些细节进行调整就ok了,比如[3,1,1,3],我们找到的第一个交换的位置为索引为0的位置这个时候我们是不能够交换索引为0与最后一个位置的数字,因为这两个数字是相等的,所以我们找到i这个位置之后,还需要从数组A的最后一个往前找一个小于A[i]的位置,并且在找的过程中有可能是遇到中间多个数字相等的情况,比如[3,1,1,3]找到的第二个交换的位置j = 2但是这个时候发现索引为1与2的位置的数字是一样的,都是为1所以这个时候我们还需要使用一个循环寻找相邻的数字不相等的位置这样我们才能够把数字大的位置放在高位,例如[3,1,1,3]交换索引为0与索引为1的位置而不是索引为0与2的位置

③ 有的时候我们需要先写出大体上的思路然后再添加一些细节上的的东西

3. 代码如下:

from typing import Listclass Solution:def prevPermOpt1(self, A: List[int]) -> List[int]:n = len(A) - 1i = nwhile i > 0 and A[i] >= A[i - 1]:i -= 1# 找到第一个交换的高位上的数字i -= 1if i >= 0:j = n# 找到第二个A[i] > A[j]的位置jwhile 0 < j != i and A[i] <= A[j]: j -= 1# 假如第二个交换的数字中相邻的数字是一样的话还要继续往前找while j > 0 and A[j] == A[j - 1]: j -= 1# 交换两个位置上的数字if i != j:A[i], A[j] = A[j], A[i]return A

1053 交换一次的先前排列(分析)相关推荐

  1. LeetCode 1053. 交换一次的先前排列

    1. 题目 给你一个正整数的数组 A(其中的元素不一定完全不同),请你返回可在 一次交换(交换两数字 A[i] 和 A[j] 的位置)后得到的.按字典序排列小于 A 的 最大可能排列. 如果无法这么操 ...

  2. 1053. 交换一次的先前排列

    给你一个正整数的数组 A(其中的元素不一定完全不同),请你返回可在 一次交换(交换两数字 A[i] 和 A[j] 的位置)后得到的.按字典序排列小于 A 的最大可能排列. 如果无法这么操作,就请返回原 ...

  3. LeetCode 1053. 交换一次的先前排列(贪心法)

    题目 思路 这道题的要求初看还是比较复杂的:既要字典序小于原来的序列,又要在小于的字典序中求出最大值.按照题目的要求,应该尽量交换排在后面的元素,因为交换越到后面的元素所产生的的字典序"增量 ...

  4. leetcode1053. 交换一次的先前排列(贪心算法)

    给你一个正整数的数组 A(其中的元素不一定完全不同),请你返回可在 一次交换(交换两数字 A[i] 和 A[j] 的位置)后得到的.按字典序排列小于 A 的最大可能排列. 如果无法这么操作,就请返回原 ...

  5. Java 数据交换格式反射机制SpringIOC原理分析

    数据交换格式&反射机制&SpringIOC原理分析 什么是数据交换格式? 数据交换格式使用场景 JSON简单使用 什么是JSON? JSON格式的分类 常用JSON解析框架 使用fas ...

  6. VOS客户端上服务器和软交换状态显示红灯的原因分析

    VOS客户端上服务器和软交换状态灯显示红灯,实际后台服务都在运行的原因 登录VOS3000客户端 原因分析  VOS客户端连接到服务器是属于TCP连接,TCP连接一旦断开后,服务器和软交换的状态灯就会 ...

  7. LeetCode 31. 下一个排列(线性扫描)

    1. 题目 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外 ...

  8. Leetcode题目分类指南(单独刷题或学习算法书籍配合使用)

    Leetcode题目分类指南 笔者在学习<算法导论>同时,希望能够配合Leetcode的题目进行分类模块化练习,该分类为笔者自己根据做题学习经验,结合<算法导论>的内容,给出L ...

  9. 如何学好C语言--你的学渣朋友告诉你

    光说不练假把式,光练不说傻把式,又练又说真把式. 真实感受,不是我不想学,是我真的不知道我哪里不会啊和得怎么做啊?本文作者当初就是这么废掉的 推荐两个练习的网站 (一)C语言网 https://www ...

最新文章

  1. P1800 software_NOI导刊2010提高(06)
  2. CentOS 6.5安装nagios
  3. dede自定义表单增加添加时间怎么弄
  4. python练习册 每天一个小程序 第0009题
  5. Android子线程中更新UI的4种方法
  6. 【NLP】如何清理文本数据
  7. 牛客网(剑指offer) 第十四题 链表中倒数第k个节点
  8. php制作图片轮播_图片轮播效果实现方法
  9. c#app.config配置文件使用
  10. asp.net 2.0 中如何让membership接口使用自定义数据库。
  11. 智能财务师 (544) -(喀麦隆)_智能财务管理师项目组到南京理工大学调研“智能会计”专业学科建设...
  12. ubuntu16.04安装mongodb
  13. Python 用装饰器便捷实现多线程
  14. 什么是 POD 数据类型
  15. 3.14 使用画笔工具给头发着色 [Ps教程]
  16. MongoDB 下载地址列表
  17. Android Wi-Fi源码分析之wpa_supplicant初始化(三):wpa_supplicant_add_iface函数分析
  18. 什么是国外广告联盟?国外广告联盟怎么赚钱?为什么你做不赚钱?
  19. 用流量扫码总显示无法连接服务器,手机有流量但无法连接网络?手机数据网络不能访问互联网...
  20. sql 注入 预防_SQL注入:检测和预防

热门文章

  1. 响应式oa管理系统php,GitHub - lsjcom/OA-SYS: OA办公系统开源项目
  2. ubuntu14.04开启wifi热点
  3. hdu 4339 Query ---线段树
  4. 四、SpringCloud——Ribbon负载均衡Ribbon自定义
  5. 7.试用期工作总结七
  6. C#:程序员快速熟悉C#
  7. Sqlite大批量导入数据提高效率的几种方式
  8. 安装了不兼容的APR(基于Apache Tomcat原生库)版本的问题解决
  9. gstreamer 中link步骤
  10. oct、dec、hex、boolalpha的作用