leetcode 31. Next Permutation (下一个排列,模拟,二分查找)
题目链接
题意
给定一段排列,输出其升序相邻的下一段排列。比如[1,3,2]的下一段排列为[2,1,3]。
注意排列呈环形,即[3,2,1]的下一段排列为[1,2,3]
思路
这个题蛮巧妙的,关键在于发现规律。假如给定的排列为[4,6,7,5],那么其下一段排列应该为[4,7,5,6]
我们可以看到除了首位的4保持不动外,后三位均发生了改变。我们可以把[4,6,7,5]看成是[4,6,5,7] -> [4,7,5,6]
这里的6称为旋转点,我们先把旋转点右边的升序([6,7,5] -> [6,5,7]),然后从升序的子数组里找到到第一个大于旋转点的值,然后交换两者的值
为什么要这么处理呢?我的一个理解是要保证相邻排列是升序的,不如先把旋转点右边的值先排序,至少保证了局部有序,
然后从局部有序的右边数组里面采用二分查找,找到第一个大于旋转点的值,交换即可满足题意。
那怎么定义旋转点呢?
可以从最右边开始往左边找,第一个小于右边相邻的数即为旋转点,如[4,6,7,5]从右边往左边找,第一个小于右边相邻的数为6(6<7, 7>5)
class Solution {
public:
//这个题,怎么说呢
//在于观察吧
//2 4 7 6-> 2 4 6 7->2 6 4 7
//模拟
void nextPermutation(vector<int>& nums) {
int n=nums.size();
if(n<=1) return ;
int j=n-2;
for(;j>=0;j--){//找到旋转点
if(nums[j]<nums[j+1]) break;
}
//把旋转点右边的数组升序
reverse(nums.begin()+j+1,nums.end());
if(j==-1) return ;
//找到和旋转点可以替换的点
auto it=upper_bound(nums.begin()+j+1,nums.end(),nums[j]);
swap(*it,nums[j]);
}
};
leetcode 31. Next Permutation (下一个排列,模拟,二分查找)的更多相关文章
- [LeetCode] 31. Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- [leetcode]31. Next Permutation下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- leetCode 31.Next Permutation (下一个字典序排序) 解题思路和方法
Next Permutation Implement next permutation, which rearranges numbers into the lexicographically ne ...
- [LeetCode] Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- 【LeetCode每天一题】Next Permutation(下一个排列)
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- LeetCode(31): 下一个排列
Medium! 题目描述: (请仔细读题) 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列) ...
- Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- 031 Next Permutation 下一个排列
实现获取下一个排列函数,这个算法需要将数字重新排列成字典序中数字更大的排列.如果不存在更大的排列,则重新将数字排列成最小的排列(即升序排列).修改必须是原地的,不开辟额外的内存空间.这是一些例子,输入 ...
- lintcode:next permutation下一个排列
题目 下一个排列 给定一个整数数组来表示排列,找出其之后的一个排列. 样例 给出排列[1,3,2,3],其下一个排列是[1,3,3,2] 给出排列[4,3,2,1],其下一个排列是[1,2,3,4] ...
- 31. Next Permutation (下一个全排列)
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
随机推荐
- Hyper-v 虚拟机使用NAT方式连接网络
最近因为搞docker的原因,卸掉了vb和vm,用上了hyper. 其实一直挺喜欢hyper-v的,但是一直都受虚拟网络的影响--hyper-v创建不了vm和vb使用的那种NAT连接方式. 默认使用外 ...
- AOP基本概念
连接点joinpoint(类中所有方法) 切入点pointcut(缺少共性代码的方法) 通知advice(被抽取的共性功能的代码逻辑,通知有位置区分,也就是从切入点方法中被抽取代码的前面还是后面抽象出 ...
- react第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制)
第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制) 课程目标 深入理解和掌握事件的冒泡及捕获机制 理解react中的合成事件的本质 在react组件中合理的使用原生事件 ...
- 一个 Spark 应用程序的完整执行流程
一个 Spark 应用程序的完整执行流程 1.编写 Spark Application 应用程序 2.打 jar 包,通过 spark-submit 提交执行 3.SparkSubmit 提交执行 4 ...
- 开源OLAP引擎对比
什么是olap 01.绝大多数请求都是读请求 02.数据以相当大的批次(>1000行)更新,而不是单行更新;或者它根本没有更新 03.数据已添加到数据库,但不会进行修改 04.对于读取,每次查询 ...
- ECharts的下载和安装(图文详解)
首先搜索找到ECharts官网,点击进入. 找到下载 进入就看到第三步,就点击在线制作 点击进入之后就自己可以选择里面的形状图,就在线制作.最后生成echarts.min.js 点击下载后就会生成js ...
- 【漏洞测试】SUDO:CVE-2019-14287
漏洞详情 sudo错误的处理了某些用户id.攻击者可以以根用户身份执行任意命令. 系统平台 kali-Linux 软件版本 1.8.27 sudo作用 非root用户不需要知道root密码,就可以执行 ...
- MySQL索引的使用是怎么样的?5个点轻松掌握!
一.前言 在MySQL中进行SQL优化的时候,经常会在一些情况下,对MySQL能否利用索引有一些迷惑. 譬如: MySQL 在遇到范围查询条件的时候就停止匹配了,那么到底是哪些范围条件? MySQL ...
- 这可能是目前最轻量级、最支持MVVM、可定制性最高的开源Chart控件!
由于项目中经常用到Series Chart,而目前市面又实在找不到既支持MVVM,又轻量级的开源Chart控件,于是干脆就花了两周时间随手写了一个.昨天感觉还比较满意,就发布到了Github上:htt ...
- Git提交错了不用慌,这三招帮你修改记录
大家好,今天我们来聊聊git当中一个很重要的功能--历史记录的修改. 有的时候我们会突然发现某个地方需要修改,最常见的某个不应该被提交的文件被提交了进来.我们希望它不只是在后序的版本当中不再出现,而是 ...