Problem: Reorder the digits of a number, in order to get the next number which is the least one that is greater than the input number. For example, the number 34724126 is the next number of 34722641 when reordering digits.
Also check http://www.ardendertat.com/2012/01/02/programming-interview-questions-24-find-next-higher-number-with-same-digits/
The analysis is great, but the implementation is kind of complex.
int firstDecreasing = getDecreasingChars(number, decreasingChars);
}
prefix = number.substring(0, firstDecreasing - 1);
}
char leastGreater = swapLeastGreater(decreasingChars, target);
resultBuilder.append(leastGreater);
return resultBuilder.toString();
}
for(; firstDecreasing > 0; --firstDecreasing) {
char curChar = number.charAt(firstDecreasing);
char preChar = number.charAt(firstDecreasing - 1);
decreasing.add(curChar);
if(curChar > preChar) {
break;
}
}
}
Read full article from Coding Interview Questions: No. 51 - Next Number with Same Set of Digits
Extended Problem 1: Given a set of digits, please output all numbers permutated by the digits in increasing order. For example, if the input are five digits 1, 2, 3, 4, 5, the output are numbers from 12345, 12354, ..., to 54321 in increasing order.
Extended Problem 2: Given a number n, please out put all numbers with n bits of 1 in increasing order. For example, if the input is 3, the output are numbers 7, 11, 13, …
I) Traverse the given number from rightmost digit, keep traversing till you find a digit which is smaller than the previously traversed digit.
II) Now search the right side of above found digit ‘d’ for the smallest digit greater than ‘d’.
III) Swap the above found two digits, we get 536974 in above example.
IV) Now sort all digits from position next to ‘d’ to the end of number. The number that we get after sorting is the output.
void
findNext(
char
number[],
int
n)
{
int
i, j;
// I) Start from the right most digit and find the first digit that is
// smaller than the digit next to it.
for
(i = n-1; i > 0; i--)
if
(number[i] > number[i-1])
break
;
// If no such digit is found, then all digits are in descending order
// means there cannot be a greater number with same set of digits
if
(i==0)
{
cout <<
"Next number is not possible"
;
return
;
}
// II) Find the smallest digit on right side of (i-1)'th digit that is
// greater than number[i-1]
int
x = number[i-1], smallest = i;
for
(j = i+1; j < n; j++)
if
(number[j] > x && number[j] < number[smallest])
smallest = j;
// III) Swap the above found smallest digit with number[i-1]
swap(&number[smallest], &number[i-1]);
// IV) Sort the digits after (i-1) in ascending order
sort(number + i, number + n);
cout <<
"Next number with same set of digits is "
<< number;
return
;
}
Also check http://www.ardendertat.com/2012/01/02/programming-interview-questions-24-find-next-higher-number-with-same-digits/
The analysis is great, but the implementation is kind of complex.
public static String getLeastGreaterNumber(String number) {
List<Character> decreasingChars = new ArrayList();int firstDecreasing = getDecreasingChars(number, decreasingChars);
if(isGreatestNumber(firstDecreasing)) {
return "";}
String prefix = "";
if(firstDecreasing > 1) {prefix = number.substring(0, firstDecreasing - 1);
}
StringBuilder resultBuilder = new StringBuilder(prefix);
char target = number.charAt(firstDecreasing - 1);char leastGreater = swapLeastGreater(decreasingChars, target);
resultBuilder.append(leastGreater);
Collections.sort(decreasingChars);
appendList(resultBuilder, decreasingChars);return resultBuilder.toString();
}
The following method getDecreasingChars gets the longest sequence of decreasing digits on the right side of a number:
private static int getDecreasingChars(String number, List<Character> decreasing) {
int firstDecreasing = number.length() - 1;private static int getDecreasingChars(String number, List<Character> decreasing) {
for(; firstDecreasing > 0; --firstDecreasing) {
char curChar = number.charAt(firstDecreasing);
char preChar = number.charAt(firstDecreasing - 1);
decreasing.add(curChar);
if(curChar > preChar) {
break;
}
}
return firstDecreasing;
}
When firstDecreasing is 0, it means all digits are increasingly sorted, and the input number is the greatest number with given digits, as listed in the following method isGreatestNumber.
private static Boolean isGreatestNumber(int firstDecreasing) {
return firstDecreasing == 0;}
Read full article from Coding Interview Questions: No. 51 - Next Number with Same Set of Digits