比如63543,这个数包含6,3,5,4,3,将这些数字重新组合以后,产生下一个较大的数字,那么就是64335。
这个问题在career cup上看到的,网上没有解答。想了一个办法,应该是没问题的。
其实题目的描述就已经给出了一个解法,就是穷举法。比如输入数字为n,将这个数字每个位上的数字求出来,存在一个数组里,然后产生它的所有排列。那么时间复杂度就是O(n!)。空间复杂度为O(log_10 n)。
下面介绍一种较好的求解方法。
观察这个数字63543,求出第一个逆序对,也就是63543。如果直接交换这两个逆序对,然后将剩下的数字升序排序,产生65334,不是所求。观察发现,如果用第一个逆序数字3与之前的有序数字中的4交换,得到64533,然后再升序排序一下之前的有序部分,得到64335,既为所求。
以下是Java实现:
import java.util.Stack; import java.util.Random; public class NextHigher { public static void swap(int[] a, int m, int n) { if (a[m] != a[n]) { a[m] ^= a[n]; a[n] ^= a[m]; a[m] ^= a[n]; } } public static int partition(int[] a, int l, int h) { int i = l - 1; int pivot = a[h]; for (int j = l; j <= h; j++) { if (a[j] < pivot) { i++; swap(a, i, j); } } swap(a, i + 1, h); return i + 1; } public static void quickSort(int[] a, int l, int h) { if (l < h) { int p = partition(a, l, h); quickSort(a, l, p - 1); quickSort(a, p + 1, h); } } public static void findNextHigher(int[] a) { if (a.length == 1) { System.out.println("No next higher number"); return; } int i = a.length - 1; for (i = a.length - 1; i >= 0; i--) { if (i < a.length - 1 && a[i] < a[i + 1]) { break; } } if (i < 0) { System.out.println("No next higher number"); return; } int diff = Integer.MAX_VALUE; int idx = 0; for (int j = i + 1; j < a.length; j++) { if (a[j] - a[i] > 0 && a[j] - a[i] < diff) { diff = a[j] - a[i]; idx = j; } } swap(a, idx, i); quickSort(a, i + 1, a.length - 1); for (int e : a) { System.out.print(e); } System.out.println(); } public static int[] numToArray(int i) { Stack<Integer> s = new Stack<Integer>(); do { s.push(i % 10); i = i / 10; } while (i != 0); int[] rtn = new int[s.size()]; i = 0; for (i = 0; i < rtn.length; i++) { rtn[i] = s.pop(); } return rtn; } public static void main(String[] args) { Random rnd = new Random(); System.out.println("Boundary case: 0 "); findNextHigher(numToArray(0)); System.out.println("Boundary case: 5 "); findNextHigher(numToArray(5)); System.out.println("Boundary case: 10 "); findNextHigher(numToArray(10)); System.out.println("Boundary case: 321 "); findNextHigher(numToArray(321)); for (int i = 0; i < 10; i++) { int num = rnd.nextInt() & 0x7fffffff; System.out.println(num); findNextHigher(numToArray(num)); } } }