您的位置:首页 > 编程语言 > Java开发

java笔试题--给定任意一个自然数,获取它重新排列后,下一个比它大的自然数

2019-03-09 01:11 155 查看
package com.zjp.start.sort;

import java.util.ArrayList;

/**
* 给定任意一个自然数,获取它重新排列后,下一个比它大的自然数,要求时间复杂度O(n)
*/
public class NextBigNum {
public static void main(String[] args) {
int num = 1347654;
String nextInt = findNextInt(num);
System.out.println(nextInt);
}

private static String findNextInt(int num) {
//将该自然数放入数组
ArrayList<Integer> nums = new ArrayList<Integer>();
while (num % 10 > 0) {
nums.add(0, num % 10);
num = num / 10;
}
//为了和原数接近,我们要保持高位不变,低位在最小范围内变换顺序
//从右向左寻找逆序区域的临界值
int cricitalPoint = findCricitalPoint(nums);
if (cricitalPoint == -1) {
//不存在
return "不存在";
} else {
//存在,就把临界值的前一个数和逆序区域中刚刚大于该数的数字交换位置,然后把逆序区域变为顺序
return reorder(nums, cricitalPoint);
}
}

/**
* 寻找逆序区域的临界值
*
* @param nums
* @return
*/
private static int findCricitalPoint(ArrayList<Integer> nums) {
for (int i = nums.size() - 1; i > 0; i--) {
if (nums.get(i) > nums.get(i - 1)) {
return i;
}
}
return -1;
}

/**
* 把逆序区域临界值的前一位和逆序区域中刚刚大于该数的数字交换位置,并把逆序区域变为顺序
*
* @param nums
* @param index
* @return
*/
private static String reorder(ArrayList<Integer> nums, int index) {
//把逆序临界值的前一位和逆序区域中刚刚大于该数的数字交换位置
//记录临界值的前一个数
int left = nums.get(index - 1);
for (int i = nums.size() - 1; i >= index; i--) {//循环逆序区域
int right = nums.get(i);
if (left < right) {
nums.set(index - 1, right);
nums.set(i, left);
break;
}
}
//把逆序区域变为顺序
for (int i = index, j = nums.size() - 1; i < j; i++, j--) {
int tmp = nums.get(i);
nums.set(i, nums.get(j));
nums.set(j, tmp);
}
return nums.toString();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐