Given a positive 32-bit integer n, you need to find the smallest 32-bit integer which has exactly the same digits existing in the integer n and is greater in value than n. If no such positive 32-bit integer exists, you need to return -1.
Example 1:
Input: 12 Output: 21
Example 2:
Input: 21 Output: -1
解释:找到一个有相同字符组成且刚好大于其自身的整形数字,找不到则返回-1。
样例比如:
input output
0 -1
11 -1
12 21
21 -1
786871 787168(而不是787861!因为题目要求刚好大于)
1999999999 -1(超过整形范围)
思路:从后向前逐个位置寻找:找到刚好大于该位置元素且差值最小的元素,将两元素交换后重排序即可。例如:
786871,长度6,下标从0到5。因为有重复元素,所以下面对每一个元素都附加下标表示,比如最高位的7,表示为7(下标0)。
round 1:对于7(下标4),1(下标5)不大于7,不符合。
round 2:对于8(下标3),1(下标5)、7(下标4)均不大于8,不符合。
round 3:对于6(下标2),8(下标3)、7(下标4)大于6,其中7与6的差值最小,所以7(下标4)为将要与6(下标2)交换位置的元素。交换二者,得到787861。但是尚不满足题意,因为要求刚好大于,而787861小的数字还有如787168等数字,所以,要对刚刚交换的位置(下标2)后的数字重新排序得到最小的数。即对8、6、1重新排序组合的到168,与之前的787组合得到答案787168。
class Solution {
public int nextGreaterElement(int n) {
char[] chs = (n + "").toCharArray();
int minindex = -1;
StringBuilder sb = new StringBuilder();
for(int i = chs.length - 2;i >= 0 ;i--){
for(int j = chs.length - 1 ;j > i ; j--){
if(chs[j] > chs[i]){
if(minindex == -1){
minindex = j;
}else if(chs[minindex] - chs[i] > chs[j] - chs[i]){
minindex = j;
}
}
}
if(minindex != -1){
char t = chs[i];
chs[i] = chs[minindex];
chs[minindex] = t;
ArrayList<Character> list = new ArrayList<Character>();
for(int a = i + 1 ;a < chs.length ;a++){
list.add(chs[a]);
}
Collections.sort(list);
for(int a = i + 1 ;a < chs.length ;a++){
chs[a] = list.get(a -(i + 1) );
}
for(char c :chs){
sb.append(c);
}
long val = Long.parseLong(sb.toString());
return (val <= Integer.MAX_VALUE) ? (int) val : -1;
}
}
return -1;
}
}