每日一道编程题——求比当前数值大的新排列
来源:互联网 发布:socket网络编程视频 编辑:程序博客网 时间:2024/06/05 04:59
求比当前数值大的新排列
题目
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
The replacement must be in-place, do not allocate extra memory.
Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3 → 1,3,23,2,1 → 1,2,31,1,5 → 1,5,1
分析
给出一个数组,以当前数组的元素顺序组成一个整数,我们要从新排列这个数组,使得新的整数比当前的整数大,且新的整数只能是当前整数的相邻值,即新的整数与现在的整数之间无法插入别的排列值。
若无法找到满足上面条件的排列,那么将数组排从小到大排列即可。
例如:
1,2,3 我们能够排列出1,3,2
,2,1,3
, 2,3,1
等等,但是结果是1,3,2
,因为132是比123大的最小的组合(213,231都比132大)。
算法
- 暴力求解:列出所有的排列组合,然后与原来的比较,这种办法的时间复杂度是n!,是一个非常差的时间复杂度。
- 利用规律求解。
例如:1,2,3,6,5,4,3,2
对于正整数而言,我们只要尽量变大低位,因为低位的变化对数值的增加较小,所以更接近答案。
我们可以从最右边开始向前比较,如果后一个数大于前一个数,那么我们要从后面的数里面找出一个数替换前一个数(即nums[i]>nums[i-1])。
在这个例子里面,我们发现6>3,所以我们要替换掉3,那用几替换呢?当然是用比3大的最小的数,那么无疑就是4了,交换3和4,得到 :1,2,4,6,5,3,3,2
这样就得到了比原来大的整数了,改低位比改高位得到的数小得多,那么还没完,我们发现在交换数之前,与交换之后,后面的数都是从大到小排列的,我们要对后面的数进行从小到大排序,只需要逆序就可以了,逆序之后:1,2,4,2,3,3,5,6
这样就得到了满足题目的要求了。
如图所示: - 代码
public class Solution { public void nextPermutation(int[] nums) { int len = nums.length; int index = 0; if(len==1) return; for(int i =len-1;i>=1;i--){ if(nums[i]>nums[i-1]){ //返回比num[i-1]大的最小的数下标 index = indexOfBigNum(nums,nums[i-1],i); //交换 int temp = nums[i-1]; nums[i-1] = nums[index]; nums[index] = temp; index = i;//记录交换的下标 break; } } //从index开始后面的数变为逆序 若无交换则从0开始逆序 reverse(nums,index); } public void reverse(int[] nums,int start){ int len = nums.length; for(int i=0;i<(len-start)/2;i++){ int temp = nums[i+start]; nums[i+start] = nums[len -1 -i]; nums[len-1-i] = temp; } } public int indexOfBigNum(int[] nums,int target,int start){ for(int i =start;i<nums.length;i++){ if((i<nums.length-1 && nums[i]>target && nums[i+1]<=target) || (i == nums.length-1 && nums[i]>target)){ return i; } } return start; }}
这个时间复杂度只有O(n)
0 0
- 每日一道编程题——求比当前数值大的新排列
- 每日一道算法题:求N个整数的最大公约数
- 每日一道算法题——1
- 每日一道算法题——2
- 生成窗口最大数值(每日一道算法题)
- 【每日一题】 -1和1的数值比…
- 每日一题(61) - 找出左边比它小,右边比它大的数
- 每日一道算法题:求数对之差的最大值
- 每日一道算法题:求一个矩阵中最大的二维矩阵(元素和最大)
- 一道笔试题(122345求有条件全排列)的两种做法
- 每天一道算法题——数值的整数次幂
- 每日一道算法题——最长回文字串
- 每日一道算法题——Container with Most Water
- 每日一道算法题——Longest Valid Parentheses
- 每日一道算法题——矩形覆盖
- 每日一道算法题5——翻转句子中单词的顺序
- 每日一道算法题7—— 查找最大(小)的k个元素
- 一道题的思考——全排列的算法实现
- 《Java虚拟机》必知必会——十四个问题总结(内存模型+GC)
- 配置SonarQube,Jenkins集成扫描Android项目
- 相思风雨中
- 入门级别spring案例
- 2.CSS图像绘制之:菜单按钮
- 每日一道编程题——求比当前数值大的新排列
- mybatis 缓存
- hadoop 安装问题总结
- WireShark找不到网卡
- 关于<Script>标签在html页面放置位置
- JAVA基础及环境配置
- js中模拟队列
- python中的列表、break、continue
- iOS多线程简单介绍(线程,进程)