JNEXT - Just Next
Problem taken from https://www.spoj.com/problems/JNEXT/
Problem
DevG likes too much fun to do with numbers. Once his friend Arya came and gave him a challenge, he gave DevG an array of digits which is forming a number currently (will be called as given number). DevG was challanged to find the just next greater number which can be formed using digits of given number. Now DevG needs your help to find that just next greater number and win the challenge.
Input
The first line have t number of test cases (1 <= t <= 100). In next 2*t lines for each test case first there is number n (1 <= n <= 1000000) which denotes the number of digits in given number and next line contains n digits of given number separated by space.
Output
Print the just next greater number if possible else print -1 in one line for each test case.
Note : There will be no test case which contains zero in starting digits of any given number.
Example
Input:
2
5
1 5 4 8 3
10
1 4 7 4 5 8 4 1 2 6
Output:
15834
1474584162
Analysis
Notations used
| Notation | Meaning |
|---|---|
| Array representation of integer | |
| An integer | |
| The just next integer obtained after permuting digits of | |
| Set of all integers obtained by any permutation of digits in | |
| Set of all indices of array | |
| Length of array |
Observations
About
Looking at the problem statement, these inferences can be made about .
About
An integer is greater than another integer if some decimal place of has a greater value than that of and more significant decimal places of are either greater or equal to that of . With that in mind, we can infer the following
Let this index corresponding to any be called
Also, when the decision point moves to the right, the value of the integer will be redused.
Revisiting
We saw that is the least integer in . This give us some valuable deductions. Firstly, has to be greater or equal to that of any other . Moreover, digit at the decision point should be lowest for compared to that of other with same decision point. More still, must be sorted in increasing order after the decision point.
Algorithm
FindNext(A, n)
decision_point = rightmost index i in A such that A[i] < A[i+1]
if not decision_point
return "Cannot permute to give a greater integer"
interchange_index = rightmost index i such that A[i] > A[decision_point]
swap A[decision_point] with A[interchange_index]
reverse A[decision_point+1,...,n] inplace
return integer value of A
Implementation in C
This solution has been accepted by spoj.com
#include <stdio.h>
#include <stdlib.h>
void findNext(int * num, int length){
int i;
int possible = 0;
int basement;
int ground;
int temp;
for(i=length-1;i>0;i--){
if(num[i] > num[i-1]){
possible = 1;
basement = i-1;
break;
}
}
if(!possible){
printf("-1\n");
return;
}
ground = basement + 1;
for(i=ground+1;i<length;i++){
if(num[i] > num[basement]){
ground = i;
} else {
break;
}
}
temp = num[basement];
num[basement] = num[ground];
num[ground] = temp;
int breakpoint = basement + 1;
for(i=0;i<breakpoint;i++){
printf("%d", num[i]);
}
for(i=length-1;i>basement;i--){
printf("%d", num[i]);
}
printf("\n");
return;
}
void main() {
int instances;
scanf("%d", &instances);
{
int i;
int length;
int num[1000000];
for(i=0;i<instances;i++){
scanf("%d", &length);
int j;
for(j=0;j<length;j++){
scanf("%d", &num[j]);
}
findNext(num, length);
}
}
}