237

I just bombed an interview and made pretty much zero progress on my interview question.

Given a number, find the next higher number which has the exact same set of digits as the original number. For example: given 38276 return 38627

I wanted to begin by finding the index of the first digit (from the right) that was less than the ones digit. Then I would rotate the last digits in the subset such that it was the next biggest number comprised of the same digits, but got stuck.

The interviewer also suggested trying to swap digits one at a time, but I couldn't figure out the algorithm and just stared at a screen for like 20-30 minutes. Needless to say, I think I'm going to have to continue the job hunt.

yivi
  • 42,438
  • 18
  • 116
  • 138
bhan
  • 2,489
  • 3
  • 19
  • 26
  • 17
    without thinking about it too much *a start at least* would be brute force calculate all permutations of the digits and grab the minimum number that is larger than the input number – BrokenGlass Feb 20 '12 at 20:53
  • 15
    in C++ you can just use `next_permutation` ;-) – thedayturns Feb 21 '12 at 06:33
  • 9
    FYI, here's how I solved it in about 15 minutes while barely even thinking about the problem: I first spent 5 minutes writing a brute-force algorithm that just created all possible permutations of a set of digits, sorted them, and displayed them. I spent 5 minutes looking through *that* data until a pattern emerged from the list (the O(n) accepted solution here became clear after just a short time looking), then I spent 5 minutes coding the O(n) algorithm. – Ben Lee Feb 21 '12 at 19:55
  • 1
    In general, this is not a bad way to come up with algorithms to solve this sort of problem when you are stuck -- use brute force on some smallish sample to create a lot of data which you can then use to see patterns more easily. – Ben Lee Feb 21 '12 at 19:58
  • 19
    I'd also like to point out, if you *really* can't figure out an efficient way to do this, doing nothing is sure way to fail the interview (and in the business world, it's a sure way to miss a product deadline). When you got stuck, instead of giving up, you should have just brute forced it and put a comment on the top "TODO: refactor for performance" or something like that. If I was interviewing and someone did that, I wouldn't necessarily fail them. At least they came up with *something that worked* AND recognized that something better was out there, even if they couldn't find it. – Ben Lee Feb 21 '12 at 20:06
  • In addition to Ben Lee's helpful comment, the way to solve these problems is to write out a simple, complete sequence (like 3 digits) and see you can see a pattern that you can turn into an algorithm. – Muhd Jul 13 '12 at 00:42
  • Don't forget to check the return value of `std::next_permutation` if you want only higher permutations. Quoting [cplusplus](http://www.cplusplus.com/reference/algorithm/next_permutation/): `If the function can determine the next higher permutation, it rearranges the elements as such and returns true. If that was not possible (because it is already at the largest possible permutation), it rearranges the elements according to the first permutation (sorted in ascending order) and returns false.` – jweyrich Oct 26 '13 at 21:11
  • I think the question should be, find the least higher number with the same digits...!! – Sandeep Feb 06 '15 at 02:42
  • how to get an even number greater than the given number using same digits? – Labeo Dec 30 '15 at 18:48
  • Answer in PHP. Time complexity O(n) https://stackoverflow.com/a/71163146/2745436 – Amitesh Bharti Feb 17 '22 at 18:03

39 Answers39

286

You can do it in O(n) (where n is the number of digits) like this:

Starting from the right, you find the first pair-of-digits such that the left-digit is smaller than the right-digit. Let's refer to the left-digit by "digit-x". Find the smallest number larger than digit-x to the right of digit-x, and place it immediately left of digit-x. Finally, sort the remaining digits in ascending order - since they were already in descending order, all you need to do is reverse them (save for digit-x, which can be placed in the correct place in O(n)).

An example will make this more clear:

123456784987654321
start with a number

123456784 987654321
         ^the first place from the right where the left-digit is less than the right  
         Digit "x" is 4

123456784 987654321
              ^find the smallest digit larger than 4 to the right

123456785 4 98764321
        ^place it to the left of 4

123456785 4 12346789
123456785123446789
         ^sort the digits to the right of 5.  Since all of them except 
         the '4' were already in descending order, all we need to do is 
         reverse their order, and find the correct place for the '4'

Proof of correctness:

Let's use capital letters to define digit-strings and lower-case for digits. The syntax AB means "the concatenation of strings A and B". < is lexicographical ordering, which is the same as integer ordering when the digit-strings are of equal length.

Our original number N is of the form AxB, where x is a single digit and B is sorted descending.
The number found by our algorithm is AyC, where y ∈ B is the smallest digit > x (it must exist due to the way x was chosen, see above), and C is sorted ascending.

Assume there is some number (using the same digits) N' such that AxB < N' < AyC. N' must begin with A or else it could not fall between them, so we can write it in the form AzD. Now our inequality is AxB < AzD < AyC, which is equivalent to xB < zD < yC where all three digit-strings contain the same digits.

In order for that to be true, we must have x <= z <= y. Since y is the smallest digit > x, z cannot be between them, so either z = x or z = y. Say z = x. Then our inequality is xB < xD < yC, which means B < D where both B and D have the same digits. However, B is sorted descending, so there is no string with those digits larger than it. Thus we cannot have B < D. Following the same steps, we see that if z = y, we cannot have D < C.

Therefore N' cannot exist, which means our algorithm correctly finds the next largest number.

BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
  • 8
    nice solution! have one question. say "the smallest digit larger than x" is y. can we just swap x and y, then reverse x.index+1 -> end? – Kent Feb 21 '12 at 09:46
  • Minor nitpick - if the number is already sorted there is no solution. – Adam Matan Feb 21 '12 at 18:30
  • 8
    What happens to the number 99999? – Sterex Feb 21 '12 at 19:46
  • @Sterex: There is no solution, so you reach the end and error out. – BlueRaja - Danny Pflughoeft Feb 21 '12 at 19:53
  • 21
    @Sterex, it's not just 99999; any number whose digits are already fully sorted in descending order is the max (so 98765 also has no solution, for example). This is easy to detect programatically because step 1 of the algorithm will fail (there is no pair of consecutive digits such that "the left-digit is smaller than the right-digit"). – Ben Lee Feb 21 '12 at 20:02
  • What about a number like 8932, where there is no number larger than digit-x to the right of digit-x? – TMN Feb 22 '12 at 17:27
  • 3
    @TMN: 9 is larger than 8, so you'd move 9 to the left of 8: `9 832` then sort everything to the right of 9: `9238` – BlueRaja - Danny Pflughoeft Feb 22 '12 at 17:40
  • 5
    @Kent for your solution to work you will have to change _find the smallest digit larger than 4 **to** the right_ to _find the smallest digit larger than 4 **from** the right_. Otherwise, for example, 1234567849876 **55** 4321 will result in 1234567851234 **54** 6789 (instead of 1234567851234 **45** 6789). A nitpick :-) – osundblad Mar 01 '12 at 12:23
  • 1
    I implemented this algorithm in Java, see [gist](https://gist.github.com/4704817) – oschrenk Feb 04 '13 at 03:09
  • 1
    @BlueRaja-DannyPflughoeft can u once tell me how it will work for 12345 the ans should be 12354 – Rajesh M May 13 '13 at 11:34
  • 1
    @souravganguly - you're to start from the right, not left. So starting from the right, the first pair where the left digit is less than the right is 4 5. Swap them -> 12354. Done. – iheanyi May 20 '14 at 23:23
  • how to get an even number greater than the given number using same digits – Labeo Dec 30 '15 at 18:48
  • i don't see how it runs in O(n) where n is the number of digit, sorting the array descending after the swapping is still O(nlogn) – Ohhh Feb 18 '16 at 21:56
  • I took it upon myself to correct it, because original comments were wrong and also did not took repetition of digits into account! – ppseprus Sep 01 '16 at 17:48
  • @ppseprus: I've rejected your edit because it does not work. For example, for `1992`, the next highest should be `2199`, which the current algorithm correctly finds. Your edit would call the first `9` "digit x" and break, because there is no _"smallest digit larger than 9 to the right.."_. If you have a counter-example that breaks with the current algorithm, please share! – BlueRaja - Danny Pflughoeft Sep 01 '16 at 18:00
  • Okay... I don't see why my solution would not work on `1992`, but lets see your logic: You say, we find "the first place where the left-digit is less-than the right-digit". The example shall be `231`. And you're right, the solution is `312`. But wait! Lets concatenate the same number twice: `231231` and your solution is `311223`, while as mine would be `213312`. And my logic actually covers `1992`, I don't see why it would not. – ppseprus Sep 01 '16 at 18:32
  • Also, I never wrote "smallest digit larger than 9 to the right.." in my edit – ppseprus Sep 01 '16 at 18:36
  • @ppseprus [Let's move this discussion to chat](http://chat.stackoverflow.com/rooms/122451/discussion-on-post-9368205) – BlueRaja - Danny Pflughoeft Sep 01 '16 at 18:38
  • Okay.. So, I wasn't careful enough reading the answer. I wasn't paying attention to the "Starting from the right" part... Sorry about it! – ppseprus Sep 01 '16 at 20:00
  • 1
    This is explained in https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order – Alfredo Osorio Jan 16 '17 at 01:11
  • The last step won't work if digits are in repetition. So we need to sort the digits from d to the last number, For sorting the digits the time complexity becomes O(nlogn). So it is not possible in O(n) with this logic. – Vipul Gupta Dec 03 '20 at 18:27
  • 2
    @VipulGupta False. Try it with an example. – BlueRaja - Danny Pflughoeft Dec 03 '20 at 18:30
  • @BlueRaja-DannyPflughoeft Yeah Got it!! Reverse the digits and find the right place for the 'x', Thankyou!! it will work!! – Vipul Gupta Dec 07 '20 at 06:58
98

An almost-identical problem appeared as a Code Jam problem and has a solution here:

http://code.google.com/codejam/contest/dashboard?c=186264#s=a&a=1

Here's a summary of the method using an example:

34722641

A. Split the sequence of digits in two, so that the right part is as long as possible while remaining in decreasing order:

34722 641

(If the entire number is in decreasing order, there's no bigger number to be made without adding digits.)

At this point, you know there is no larger number that starts with the left part, because the right part is already as large as possible with the leftover digits.

B.1. Select the last digit of the first sequence:

3472(2) 641

B.2. Find the smallest digit in the second sequence that is larger than it:

3472(2) 6(4)1

What you're doing is finding the smallest possible increase to the left part.

B.3. Swap them:

3472(2) 6(4)1
->
3472(4) 6(2)1
->
34724 621

C. Sort the second sequence into increasing order:

34724 126

D. Done!

34724126

You split the number such that you knew there was no larger number with the same left part, you increased the left part by the smallest amount possible, and you made the remaining right part as small as possible, so you can be sure this new number is the smallest larger number that can be made with the same collection of digits.

Weeble
  • 17,058
  • 3
  • 60
  • 75
  • 1
    Typo there: I think "-> 34721 621" should be "-> 34724 621" ? – bjnord Feb 22 '12 at 16:50
  • 1
    @bjnord Good catch. Fixed. Not sure how I managed that - it was correct in subsequent lines. – Weeble Feb 22 '12 at 16:57
  • +1 Best answer here. Intuitive and fast. (it's also the the one I thought of when I worked this out on paper ;) ) – Muhd Jul 13 '12 at 00:54
  • What will be the running time? Linearithmic? Can it be Linear? – Neel Apr 29 '13 at 14:20
  • @Neel If you use a linearithmic sort, this will be linearithmic. If you just reverse the digits on the right and search for the right spot to insert the swapped digit, it can be linear. It's basically the same algorithm as BlueRaja's, just explained slightly differently. – Weeble Apr 29 '13 at 14:53
  • @Weebie- We can do swapping without reversing. Why do you want to reverse the second part? Sorting and swap are independent. How will you sort the second part in linear time? – Neel Apr 29 '13 at 19:59
  • 1
    @Neel - In step C, the digits we want to sort are in descending order, except for the digit we swapped in at step B. To sort them we actually only need to reverse them and get the swapped digit into the right position. This is what BlueRaja describes. – Weeble Apr 30 '13 at 08:00
  • in case 123 what will be answer? Practically u'll code will not generate output while it shold come 132 – Dhaval dave Sep 16 '13 at 16:58
  • 1
    @Dhavaldave What's the problem? In step A you get "12" and "3". In step B you get "13" and "2". In step C nothing changes. In step D you get "132". The only case where you won't get an answer is when the number is already the maximum possible, e.g. "321". In that case, step A gives you "" and "321", and you can't proceed with an empty sequence for the left side of the split. – Weeble Sep 17 '13 at 09:42
14

Here's a compact (but partly brute force) solution in Python

def findnext(ii): return min(v for v in (int("".join(x)) for x in
    itertools.permutations(str(ii))) if v>ii)

In C++ you could make the permutations like this: https://stackoverflow.com/a/9243091/1149664 (It's the same algorithm as the one in itertools)

Here's an implementation of the top answer described by Weeble and BlueRaja, (other answers). I doubt there's anything better.

def findnext(ii):
    iis=list(map(int,str(ii)))
    for i in reversed(range(len(iis))):
        if i == 0: return ii
        if iis[i] > iis[i-1] :
            break        
    left,right=iis[:i],iis[i:]
    for k in reversed(range(len(right))):
        if right[k]>left[-1]:
           right[k],left[-1]=left[-1],right[k]
           break
    return int("".join(map(str,(left+sorted(right)))))
Johan Lundberg
  • 26,184
  • 12
  • 71
  • 97
8

At minimum, here are a couple of example brute force String based solutions, that you should have been able to come up with right off the top of your head:

the list of digits in 38276 sorted is 23678

the list of digits in 38627 sorted is 23678

brute force increment, sort and compare

Along the brute force solutions would be convert to a String and brute force all the possible numbers using those digits.

Create ints out of them all, put them in a list and sort it, get the next entry after the target entry.

If you spent 30 minutes on this and didn't at least come up with at least a brute force approach, I wouldn't hire you either.

In the business world, a solution that is inelegant, slow and clunky but gets the job done is always more valuable than no solution at all, matter of fact that pretty much describes all business software, inelegant, slow and clunky.

  • 1
    Well my first comment off the bat was "I could brute force it but...". If there really isn't an algorithmic solution, I'm kind of disappointed – bhan Feb 20 '12 at 21:01
  • 4
    If I was the interviewer, I wouldn't be so happy with a brute force approach. – Ahmad Y. Saleh Feb 20 '12 at 21:03
  • @benjamin han, there is algorithmic solution. Just keep swaping digits starting from right, till you find the result. There's no need to compute all permutatnios before. – dantuch Feb 20 '12 at 21:04
  • 7
    There certainly are much better solutions than brute force, e.g. http://www.ardendertat.com/2012/01/02/programming-interview-questions-24-find-next-higher-number-with-same-digits/ – BrokenGlass Feb 20 '12 at 21:04
  • @BrokenGlass Definitely a much better solution. I was just coming up with that idea and then you posted the algorithm. – onit Feb 20 '12 at 21:10
  • a brute force approach is a solution, better than no solution at all. –  Feb 20 '12 at 21:27
  • @Ahmad a solution is better than **no** solution, which is what they ended up with. That is my point. –  Feb 20 '12 at 21:33
5
function foo(num){
 sortOld = num.toString().split("").sort().join('');
 do{
    num++;
   sortNew = num.toString().split("").sort().join('');
 }while(sortNew!==sortOld);
 return num;
}
Ashikodi
  • 1,090
  • 1
  • 9
  • 9
4

Your idea

I wanted to begin by finding the index of the first digit (from the right) that was less than the ones digit. Then I would rotate the last digits in the subset such that it was the next biggest number comprised of the same digits, but got stuck.

is pretty good, actually. You just have to consider not only the last digit but all digits of less significance than the currently considered. Since before that is reached, we have a monotonic sequence of digits, that is the rightmost digit smaller than its right neighbour. Regard

1234675
    ^

The next larger number having the same digits is

1234756

The found digit is exchanged for the last digit - the smallest of the considered digits - and the remaining digits are arranged in increasing order.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
4

I'm fairly sure your interviewer was trying to push you gently towards something like this:

local number = 564321;

function split(str)
    local t = {};
    for i = 1, string.len(str) do
        table.insert(t, str.sub(str,i,i));
    end
    return t;
end

local res = number;
local i = 1;
while number >= res do
    local t = split(tostring(res));
    if i == 1 then
        i = #t;
    end
    t[i], t[i-1] = t[i-1], t[i];
    i = i - 1;
    res = tonumber(table.concat(t));
end

print(res);

Not necessarily the most efficient or elegant solution but it solves the provided example in two cycles and swaps digits one at a time like he suggested.

Lexi
  • 1,670
  • 1
  • 19
  • 35
2

That is very interesting question.

Here is my java version. Take me about 3 hours from figuring out the pattern to completely finish the code before I checked other contributors' comments. Glad to see my idea is quite same with others.

O(n) solution. Honestly, I will fail this interview if the time is only 15 minutes and require complete code finish on white board.

Here are some points of interesting for my solution:

  • Avoid any sorting .
  • Avoid string operation completely
  • Achieve O(logN) space complexity

I put detail comment in my code, and the Big O in each step.

  public int findNextBiggestNumber(int input  )   {
    //take 1358642 as input for example.
    //Step 1: split the whole number to a list for individual digital   1358642->[2,4,6,8,5,3,1]
    // this step is O(n)
    int digitalLevel=input;

    List<Integer> orgNumbersList=new ArrayList<Integer>()   ;

    do {
        Integer nInt = new Integer(digitalLevel % 10);
        orgNumbersList.add(nInt);

        digitalLevel=(int) (digitalLevel/10  )  ;


    } while( digitalLevel >0)    ;
    int len= orgNumbersList.size();
    int [] orgNumbers=new int[len]  ;
    for(int i=0;i<len;i++){
        orgNumbers[i ]  =  orgNumbersList.get(i).intValue();
    }
    //step 2 find the first digital less than the digital right to it
    // this step is O(n)


    int firstLessPointer=1;
    while(firstLessPointer<len&&(orgNumbers[firstLessPointer]>orgNumbers[ firstLessPointer-1 ])){
        firstLessPointer++;
    }
     if(firstLessPointer==len-1&&orgNumbers[len-1]>=orgNumbers[len-2]){
         //all number is in sorted order like 4321, no answer for it, return original
         return input;
     }

    //when step 2 step finished, firstLessPointer  pointing to number 5

     //step 3 fristLessPointer found, need to find  to  first number less than it  from low digital in the number
    //This step is O(n)
    int justBiggerPointer=  0 ;

    while(justBiggerPointer<firstLessPointer&& orgNumbers[justBiggerPointer]<orgNumbers[firstLessPointer]){
        justBiggerPointer++;
    }
    //when step 3 finished, justBiggerPointer  pointing to 6

    //step 4 swap the elements  of justBiggerPointer and firstLessPointer .
    // This  is O(1) operation   for swap

   int tmp=  orgNumbers[firstLessPointer] ;

    orgNumbers[firstLessPointer]=  orgNumbers[justBiggerPointer]  ;
     orgNumbers[justBiggerPointer]=tmp ;


     // when step 4 finished, the list looks like        [2,4,5,8,6,3,1]    the digital in the list before
     // firstLessPointer is already sorted in our previous operation
     // we can return result from this list  but  in a differrent way
    int result=0;
    int i=0;
    int lowPointer=firstLessPointer;
    //the following pick number from list from  the position just before firstLessPointer, here is 8 -> 5 -> 4 -> 2
    //This Operation is O(n)
    while(lowPointer>0)        {
        result+= orgNumbers[--lowPointer]* Math.pow(10,i);
        i++;
    }
    //the following pick number from list   from position firstLessPointer
    //This Operation is O(n)
    while(firstLessPointer<len)        {
        result+= orgNumbers[firstLessPointer++ ]* Math.pow(10,i);
        i++;
    }
     return  result;

}

Here is result running in Intellj:

959879532-->959892357
1358642-->1362458
1234567-->1234576
77654321-->77654321
38276-->38627
47-->74
Boveyking
  • 49
  • 3
2

A javascript implementation of @BlueRaja's algorithm.

var Bar = function(num){ 
  num = num.toString();
  var max = 0;
  for(var i=num.length-2; i>0; i--){
    var numArray = num.substr(i).split("");
    max = Math.max.apply(Math,numArray);
    if(numArray[0]<max){
        numArray.sort(function(a,b){return a-b;});
        numArray.splice(-1);
        numArray = numArray.join("");
        return Number(num.substr(0,i)+max+numArray);
    }
  }
  return -1;
};
neddinn
  • 66
  • 2
2

PHP Code

function NextHigherNumber($num1){
$num = strval($num1);
$max = 0;
for($i=(strlen($num)-2); $i>=0; $i--){
    $numArrayRaw = substr($num, $i);
    $numArray = str_split($numArrayRaw);
    $max = max($numArray);
    if ($numArray[0] < $max){
        sort( $numArray, SORT_NUMERIC );
        array_pop($numArray);
        $numarrstr = implode("",$numArray);
        $rt = substr($num,0,$i) . $max . $numarrstr;
        return $rt;
    }
}
return "-1";
}
echo NextHigherNumber(123);
2

Take a number and split it into digits. So if we have a 5 digit number, we have 5 digits: abcde

Now swap d and e and compare with the original number, if it is larger, you have your answer.

If it isn't larger, swap e and c. Now compare and if it is smaller swap d and e again (notice recursion), take smallest.

Carry on through until you find a larger number. With recursion it should work out as about 9 lines of scheme, or 20 of c#.

Roland
  • 146
  • 1
  • 1
  • 6
1

I didn't know anything about the brute force algorithm when answering this question, so I approached it from another angle. I decided to search the entire range of possible solutions that this number could possibly be rearranged into, starting from the number_given+1 up to the max number available (999 for a 3 digit number, 9999 for 4 digits, etc.). I did this kind of like finding a palindrome with words, by sorting the numbers of each solution and comparing it to the sorted number given as the parameter. I then simply returned the first solution in the array of solutions, as this would be the next possible value.

Here is my code in Ruby:

def PermutationStep(num)

    a = []
    (num.to_s.length).times { a.push("9") }
    max_num = a.join('').to_i
    verify = num.to_s.split('').sort
    matches = ((num+1)..max_num).select {|n| n.to_s.split('').sort == verify }

    if matches.length < 1
      return -1
    else
      matches[0]
    end
end
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
Jeremiah McCurdy
  • 592
  • 4
  • 11
  • what is the time complexity of this solution? – Nitish Upreti Jul 16 '14 at 06:19
  • @Myth17 I'm not sure, as I never tested it. If you'd like to figure it out though, check out this post: http://stackoverflow.com/questions/9958299/a-tool-for-calculating-the-big-o-time-complexity-of-java-code – Jeremiah McCurdy Jul 17 '14 at 08:40
1

A solution (in Java) could be the following (I am sure friends here can find a better):
Start swapping digits from the end of the string until you get a higher number.
I.e. first start moving up the lower digit.Then the next higher etc until you hit the next higher.
Then sort the rest. In your example you would get:

38276 --> 38267 (smaller) --> 38627 Found it    
    ^        ^                  ^        

 public static int nextDigit(int number){
    String num = String.valueOf(number);        
    int stop = 0;       
    char [] chars = null;
    outer:
        for(int i = num.length() - 1; i > 0; i--){          
            chars = num.toCharArray();
            for(int j = i; j > 0; j--){
                char temp = chars[j];
                chars[j] = chars[j - 1];
                chars[j - 1] = temp;
                if(Integer.valueOf(new String(chars)) > number){
                    stop = j;                   
                    break outer;                                
                }               
            }               
        }

    Arrays.sort(chars, stop, chars.length); 
    return Integer.valueOf(new String(chars));
}
Cratylus
  • 52,998
  • 69
  • 209
  • 339
1

If you are programming in C++, you could use next_permutation:

#include <algorithm>
#include <string>
#include <iostream>

int main(int argc, char **argv) {
  using namespace std; 
   string x;
   while (cin >> x) {
    cout << x << " -> ";
    next_permutation(x.begin(),x.end());
    cout << x << "\n";
  }
  return 0;
}
nibot
  • 14,428
  • 8
  • 54
  • 58
0

Here is my code, it's a modified version of this example

Library:

class NumPermExample
{
    // print N! permutation of the characters of the string s (in order)
    public  static void perm1(String s, ArrayList<String> perm)
    {
        perm1("", s);
    }

    private static void perm1(String prefix, String s, ArrayList<String> perm)
    {
        int N = s.length();
        if (N == 0)
        {
            System.out.println(prefix);
            perm.add(prefix);
        }
        else
        {
            for (int i = 0; i < N; i++)
                perm1(prefix + s.charAt(i), s.substring(0, i)
                    + s.substring(i+1, N));
        }

    }

    // print N! permutation of the elements of array a (not in order)
    public static void perm2(String s, ArrayList<String> perm)
    {
       int N = s.length();
       char[] a = new char[N];
       for (int i = 0; i < N; i++)
           a[i] = s.charAt(i);
       perm2(a, N);
    }

    private static void perm2(char[] a, int n, ArrayList<String> perm)
    {
        if (n == 1)
        {
            System.out.println(a);
            perm.add(new String(a));
            return;
        }

        for (int i = 0; i < n; i++)
        {
            swap(a, i, n-1);
            perm2(a, n-1);
            swap(a, i, n-1);
        }
    }  

    // swap the characters at indices i and j
    private static void swap(char[] a, int i, int j)
    {
        char c;
        c = a[i]; a[i] = a[j]; a[j] = c;
    }

    // next higher permutation
    public static int nextPermutation (int number)
    {
        ArrayList<String> perm = new ArrayList<String>();

        String cur = ""+number;

        int nextPerm = 0;

        perm1(cur, perm);

        for (String s : perm)
        {
            if (Integer.parseInt(s) > number
                        && (nextPerm == 0 ||
                            Integer.parseInt(s) < nextPerm))
            {
                nextPerm = Integer.parseInt(s);
            }
        }

            return nextPerm;
    }
}

Test:

public static void main(String[] args) 
{
    int a = 38276;

    int b = NumPermExample.nextPermutation(a);

    System.out.println("a: "+a+", b: "+b);
}
Khaled.K
  • 5,828
  • 1
  • 33
  • 51
0

Add 9 to the given n digit number. Then check if it is within the limit(the first (n+1) digit number). If it is then check if the digits in the new number are the same as the digits in the original number. Repeat adding 9 until both the conditions are true. Stop the algo when the number goes beyond the limit.

I could not come up with a contradicting test case for this method.

  • 1
    It works, but extremely slowly. It's an exponential time algorithm where this could be solved in linear time. – interjay Jun 17 '13 at 17:19
0
#include<stdio.h>
#include<cstring>
#include<iostream>
#include<string.h>
#include<sstream>
#include<iostream>

using namespace std;
int compare (const void * a, const void * b)
{
    return *(char*)a-*(char*)b;
}

/*-----------------------------------------------*/

int main()
{
    char number[200],temp;
    cout<<"please enter your number?"<<endl;
    gets(number);
    int n=strlen(number),length;
    length=n;
    while(--n>0)
    {
        if(number[n-1]<number[n])
        {
            for(int i=length-1;i>=n;i--)
            {
                if(number[i]>number[n-1])
                {
                    temp=number[i];
                    number[i]=number[n-1];
                    number[n-1]=temp;
                    break;
                }
            }
            qsort(number+n,length-n,sizeof(char),compare);
            puts(number); 
            return 0;
        }
    }
    cout<<"sorry itz the greatest one :)"<<endl;
}
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
0

Just another solution using python:

def PermutationStep(num):
    if sorted(list(str(num)), reverse=True) == list(str(num)):
        return -1
    ls = list(str(num))
    n = 0
    inx = 0
    for ind, i in enumerate(ls[::-1]):
        if i < n:
            n = i
            inx = -(ind + 1)
            break
        n = i
    ls[inx], ls[inx + 1] = ls[inx + 1], ls[inx]

    nl = ls[inx::-1][::-1]
    ln = sorted(ls[inx+1:])
    return ''.join(nl) + ''.join(ln)

print PermutationStep(23514)

Output:

23541
James Sapam
  • 16,036
  • 12
  • 50
  • 73
0
public static void findNext(long number){

        /* convert long to string builder */    

        StringBuilder s = new StringBuilder();
        s.append(number);
        int N = s.length();
        int index=-1,pivot=-1;

/* from tens position find the number (called pivot) less than the number in right */ 

        for(int i=N-2;i>=0;i--){

             int a = s.charAt(i)-'0';
             int b = s.charAt(i+1)-'0';

             if(a<b){
                pivot = a;
                index =i;
                break;
            }
        }

      /* if no such pivot then no solution */   

        if(pivot==-1) System.out.println(" No such number ")

        else{   

     /* find the minimum highest number to the right higher than the pivot */

            int nextHighest=Integer.MAX_VALUE, swapIndex=-1;

            for(int i=index+1;i<N;i++){

            int a = s.charAt(i)-'0';

            if(a>pivot && a<nextHighest){
                    nextHighest = a;
                    swapIndex=i;
                }
            }


     /* swap the pivot and next highest number */

            s.replace(index,index+1,""+nextHighest);
            s.replace(swapIndex,swapIndex+1,""+pivot);

/* sort everything to right of pivot and replace the sorted answer to right of pivot */

            char [] sort = s.substring(index+1).toCharArray();
            Arrays.sort(sort);

            s.replace(index+1,N,String.copyValueOf(sort));

            System.out.println("next highest number is "+s);
        }

    }
sreeprasad
  • 3,242
  • 3
  • 27
  • 33
0

Below is the code to generate all permutations of a number .. though one has to convert that integer to string using String.valueOf(integer) first.

/**
 * 
 * Inserts a integer at any index around string.
 * 
 * @param number
 * @param position
 * @param item
 * @return
 */
public String insertToNumberStringAtPosition(String number, int position,
        int item) {
    String temp = null;
    if (position >= number.length()) {
        temp = number + item;
    } else {
        temp = number.substring(0, position) + item
                + number.substring(position, number.length());
    }
    return temp;
}

/**
 * To generate permutations of a number.
 * 
 * @param number
 * @return
 */
public List<String> permuteNumber(String number) {
    List<String> permutations = new ArrayList<String>();
    if (number.length() == 1) {
        permutations.add(number);
        return permutations;
    }
    // else
    int inserterDig = (int) (number.charAt(0) - '0');
    Iterator<String> iterator = permuteNumber(number.substring(1))
            .iterator();
    while (iterator.hasNext()) {
        String subPerm = iterator.next();
        for (int dig = 0; dig <= subPerm.length(); dig++) {
            permutations.add(insertToNumberStringAtPosition(subPerm, dig,
                    inserterDig));
        }
    }
    return permutations;
}
shashi
  • 181
  • 5
0
#include<bits/stdc++.h>
using namespace std;
int main() 
{
    int i,j,k,min,len,diff,z,u=0,f=0,flag=0;
    char temp[100],a[100]`enter code here`,n;
    min=9999;
    //cout<<"Enter the number\n";
    cin>>a;
    len=strlen(a);
    for(i=0;i<len;i++)
    {
        if(a[i]<a[i+1]){flag=1;break;}
    }
    if(flag==0){cout<<a<<endl;}
    else
    {
        for(i=len-1;i>=0;i--)if(((int)a[i-1])<((int)a[i]))break;
        for(k=0;k<i-1;k++)cout<<a[k];
        for(j=i;j<len;j++)
        {
            if(((int)a[j]-48)-((int)a[i-1]-48)>0)
            {
                diff=((int)a[j]-48)-((int)a[i-1]-48);
                if(diff<min){n=a[j];min=diff;}
            }
        }
        cout<<n;
        for(z=i-1;z<len;z++)
        {
            temp[u]=a[z];
            u++;
        }
        temp[u]='\0';
        sort(temp,temp+strlen(temp));
        for(z=0;z<strlen(temp);z++){if(temp[z]==n&&f==0){f=1;continue;}cout<<temp[z];}
    }
    return 0;
}
Ujjwal Gulecha
  • 183
  • 1
  • 12
0

Here is my implementation of it in Ruby:

def foo num  
  num = num.to_s.chars.map(&:to_i)
  return num.join.to_i if num.size < 2
  for left in (num.size-2).downto(0) do
    for right in (num.size-1).downto(left+1) do
      if num[right]>num[left]
        num[left],num[right] = num[right],num[left]        
        return (num[0..left] + num[left+1..num.size-1].sort).join.to_i
      end
    end
  end
  return num.join.to_i
end

p foo 38276 
#will print: 38627
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
Sagiv Ofek
  • 25,190
  • 8
  • 60
  • 55
0

Yet another Java implementation, runnable out of the box and completed with tests. This solution is O(n) space and time using good old dynamic programming.

If one wants to bruteforce, there are 2 kinds of bruteforce:

  1. Permute all the things, then pick min higher: O(n!)

  2. Similar to this implementation, but instead of DP, bruteforcing the step of populating the indexToIndexOfNextSmallerLeft map will run in O(n^2).


import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class NextHigherSameDigits {

    public long next(final long num) {
        final char[] chars = String.valueOf(num).toCharArray();
        final int[] digits = new int[chars.length];
        for (int i = 0; i < chars.length; i++) {
            digits[i] = Character.getNumericValue(chars[i]);
        }

        final Map<Integer, Integer> indexToIndexOfNextSmallerLeft = new HashMap<>();
        indexToIndexOfNextSmallerLeft.put(1, digits[1] > digits[0] ? 0 : null);
        for (int i = 2; i < digits.length; i++) {
            final int left = digits[i - 1];
            final int current = digits[i];
            Integer indexOfNextSmallerLeft = null;
            if (current > left) {
                indexOfNextSmallerLeft = i - 1;
            } else {
                final Integer indexOfnextSmallerLeftOfLeft = indexToIndexOfNextSmallerLeft.get(i - 1);
                final Integer nextSmallerLeftOfLeft = indexOfnextSmallerLeftOfLeft == null ? null : 
                    digits[indexOfnextSmallerLeftOfLeft];

                if (nextSmallerLeftOfLeft != null && current > nextSmallerLeftOfLeft) {
                    indexOfNextSmallerLeft = indexOfnextSmallerLeftOfLeft;
                } else {
                    indexOfNextSmallerLeft = null;
                }
            }

            indexToIndexOfNextSmallerLeft.put(i, indexOfNextSmallerLeft);
        }

        Integer maxOfindexOfNextSmallerLeft = null;
        Integer indexOfMinToSwapWithNextSmallerLeft = null;
        for (int i = digits.length - 1; i >= 1; i--) {
            final Integer indexOfNextSmallerLeft = indexToIndexOfNextSmallerLeft.get(i);
            if (maxOfindexOfNextSmallerLeft == null ||
                    (indexOfNextSmallerLeft != null && indexOfNextSmallerLeft > maxOfindexOfNextSmallerLeft)) {

                maxOfindexOfNextSmallerLeft = indexOfNextSmallerLeft;
                if (maxOfindexOfNextSmallerLeft != null && (indexOfMinToSwapWithNextSmallerLeft == null || 
                        digits[i] < digits[indexOfMinToSwapWithNextSmallerLeft])) {

                    indexOfMinToSwapWithNextSmallerLeft = i;
                }
            }
        }

        if (maxOfindexOfNextSmallerLeft == null) {
            return -1;
        } else {
            swap(digits, indexOfMinToSwapWithNextSmallerLeft, maxOfindexOfNextSmallerLeft);
            reverseRemainingOfArray(digits, maxOfindexOfNextSmallerLeft + 1);
            return backToLong(digits);
        }
    }

    private void reverseRemainingOfArray(final int[] digits, final int startIndex) {
        final int[] tail = Arrays.copyOfRange(digits, startIndex, digits.length);
        for (int i = tail.length - 1; i >= 0; i--) {
            digits[(digits.length - 1)  - i] = tail[i];                 
        }
    }

    private void swap(final int[] digits, final int currentIndex, final int indexOfNextSmallerLeft) {
        int temp = digits[currentIndex];
        digits[currentIndex] = digits[indexOfNextSmallerLeft];
        digits[indexOfNextSmallerLeft] = temp;
    }

    private long backToLong(int[] digits) {     
        StringBuilder sb = new StringBuilder();
        for (long i : digits) {
            sb.append(String.valueOf(i));
        }

        return Long.parseLong(sb.toString());
    }

    @Test
    public void test() {
        final long input1 =    34722641;
        final long expected1 = 34724126;
        final long output1 = new NextHigherSameDigits().next(input1);
        assertEquals(expected1, output1);

        final long input2 =    38276;
        final long expected2 = 38627;
        final long output2 = new NextHigherSameDigits().next(input2);
        assertEquals(expected2, output2);

        final long input3 =    54321;
        final long expected3 = -1;
        final long output3 = new NextHigherSameDigits().next(input3);
        assertEquals(expected3, output3);

        final long input4 =    123456784987654321L;
        final long expected4 = 123456785123446789L;
        final long output4 = new NextHigherSameDigits().next(input4);
        assertEquals(expected4, output4);

        final long input5 =    9999;
        final long expected5 = -1;
        final long output5 = new NextHigherSameDigits().next(input5);
        assertEquals(expected5, output5);
    }

}
PoweredByRice
  • 2,479
  • 1
  • 20
  • 26
0

We need to find the right most bit 0 followed by a 1 and flip this right most 0 bit to a 1.

for example lets say our input is 487, which is 111100111 in binary.

we flip the right most 0 that has 1 following it

so we get 111101111

but now we have a extra 1 and one less 0, so we reduce the number of 1's on the right of the flip bit by 1 and increase the no of 0 bits by 1, yielding

111101011 - binary 491

int getNextNumber(int input)
{
    int flipPosition=0;
    int trailingZeros=0;
    int trailingOnes=0;
    int copy = input;

    //count trailing zeros
    while(copy != 0 && (copy&1) == 0 )
    {
        ++trailingZeros;

        //test next bit
        copy = copy >> 1;
    }

    //count trailing ones
    while(copy != 0 && (copy&1) == 1 )
    {
        ++trailingOnes;

        //test next bit
        copy = copy >> 1;
    }

    //if we have no 1's (i.e input is 0) we cannot form another pattern with 
    //the same number of 1's which will increment the input, or if we have leading consecutive
    //ones followed by consecutive 0's up to the maximum bit size of a int
    //we cannot increase the input whilst preserving the original no of 0's and
    //1's in the bit pattern
    if(trailingZeros + trailingOnes  == 0 || trailingZeros + trailingOnes == 31)
        return -1;

    //flip first 0 followed by a 1 found from the right of the bit pattern
    flipPosition = trailingZeros + trailingOnes+1;
    input |= 1<<(trailingZeros+trailingOnes);

    //clear fields to the right of the flip position
    int mask = ~0 << (trailingZeros+trailingOnes);
    input &= mask;

    //insert a bit pattern to the right of the flip position that will contain
    //one less 1 to compensate for the bit we switched from 0 to 1
    int insert = flipPosition-1;
    input |= insert;

    return input;
}
gilla07
  • 61
  • 2
0
int t,k,num3,num5;
scanf("%d",&t);
int num[t];
for(int i=0;i<t;i++){
    scanf("%d",&num[i]);   
}
for(int i=0;i<t;i++){
    k=(((num[i]-1)/3)+1); 
    if(k<0)
        printf("-1");
    else if(num[i]<3 || num[i]==4 || num[i]==7)
        printf("-1");
    else{
        num3=3*(2*num[i] - 5*k);
        num5=5*(3*k -num[i]);
        for(int j=0;j<num3;j++)
            printf("5");
        for(int j=0;j<num5;j++)
            printf("3");
    }
    printf("\n");
}
0

Here is the Java Implementation

public static int nextHigherNumber(int number) {
    Integer[] array = convertToArray(number);
    int pivotIndex = pivotMaxIndex(array);
    int digitInFirstSequence = pivotIndex -1;
    int lowerDigitIndexInSecondSequence = lowerDigitIndex(array[digitInFirstSequence], array, pivotIndex);
    swap(array, digitInFirstSequence, lowerDigitIndexInSecondSequence);
    doRercursiveQuickSort(array, pivotIndex, array.length - 1);
    return arrayToInteger(array);
}

public static Integer[] convertToArray(int number) {
    int i = 0;
    int length = (int) Math.log10(number);
    int divisor = (int) Math.pow(10, length);
    Integer temp[] = new Integer[length + 1];

    while (number != 0) {
        temp[i] = number / divisor;
        if (i < length) {
            ++i;
        }
        number = number % divisor;
        if (i != 0) {
            divisor = divisor / 10;
        }
    }
    return temp;
}

private static int pivotMaxIndex(Integer[] array) {
    int index = array.length - 1;
    while(index > 0) {
        if (array[index-1] < array[index]) {
            break;
        }
        index--;
    }       
    return index;
}

private static int lowerDigitIndex(int number, Integer[] array, int fromIndex) {
    int lowerMaxIndex = fromIndex;
    int lowerMax = array[lowerMaxIndex];
    while (fromIndex < array.length - 1) {
        if (array[fromIndex]> number && lowerMax > array[fromIndex]) {
            lowerMaxIndex = fromIndex; 
        }
        fromIndex ++;
    }
    return lowerMaxIndex;
}

public static int arrayToInteger(Integer[] array) {
    int number = 0;
    for (int i = 0; i < array.length; i++) {
        number+=array[i] * Math.pow(10, array.length-1-i);
    }
    return number;
}

Here is the Unit Tests

@Test
public void nextHigherNumberTest() {
    assertThat(ArrayUtils.nextHigherNumber(34722641), is(34724126));
    assertThat(ArrayUtils.nextHigherNumber(123), is(132));
}
craftsmannadeem
  • 2,665
  • 26
  • 22
0

I know this is very old question but still I didn't find easy code in c#. This might help guys who are attending interviews.

class Program
{
    static void Main(string[] args)
    {

        int inputNumber = 629;
        int i, currentIndexOfNewArray = 0;

        int[] arrayOfInput = GetIntArray(inputNumber);
        var numList = arrayOfInput.ToList();

        int[] newArray = new int[arrayOfInput.Length];

        do
        {
            int temp = 0;
            int digitFoundAt = 0;
            for (i = numList.Count; i > 0; i--)
            {
                if (numList[i - 1] > temp)
                {
                    temp = numList[i - 1];
                    digitFoundAt = i - 1;
                }
            }

            newArray[currentIndexOfNewArray] = temp;
            currentIndexOfNewArray++;
            numList.RemoveAt(digitFoundAt);
        } while (arrayOfInput.Length > currentIndexOfNewArray);



        Console.WriteLine(GetWholeNumber(newArray));

        Console.ReadKey();


    }

    public static int[] GetIntArray(int num)
    {
        IList<int> listOfInts = new List<int>();
        while (num > 0)
        {
            listOfInts.Add(num % 10);
            num = num / 10;
        }
        listOfInts.Reverse();
        return listOfInts.ToArray();
    }

    public static double GetWholeNumber(int[] arrayNumber)
    {
        double result = 0;
        double multiplier = 0;
        var length = arrayNumber.Count() - 1;
        for(int i = 0; i < arrayNumber.Count(); i++)
        {
            multiplier = Math.Pow(10.0, Convert.ToDouble(length));
            result += (arrayNumber[i] * multiplier);
            length = length - 1;
        }

        return result;
    }
}
Arul
  • 71
  • 1
  • 1
  • I checked out your code and received wrong result, for example if we have the number 1234126 we will expect 1234162, but we received 6432211. – JustName Jul 05 '21 at 16:32
0

Very simple implementation using Javascript, next highest number with same digits

/*
Algorithm applied
I) Traverse the given number from rightmost digit, keep traversing till you find a digit which is smaller than the previously traversed digit. For example, if the input number is “534976”, we stop at 4 because 4 is smaller than next digit 9. If we do not find such a digit, then output is “Not Possible”.

II) Now search the right side of above found digit ‘d’ for the smallest digit greater than ‘d’. For “534976″, the right side of 4 contains “976”. The smallest digit greater than 4 is 6.

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. For above example, we sort digits in bold 536974. We get “536479” which is the next greater number for input 534976.

*/

function findNext(arr)
{
  let i;
  //breaking down a digit into arrays of string and then converting back that array to number array
  let arr1=arr.toString().split('').map(Number) ;
  //started to loop from the end of array 
  for(i=arr1.length;i>0;i--)
  {
    //looking for if the current number is greater than the number next to it
    if(arr1[i]>arr1[i-1])
    {// if yes then we break the loop it so that we can swap and sort
      break;}
  }

  if(i==0)
  {console.log("Not possible");}

   else
  {
   //saving that big number and smaller number to the left of it
   let smlNum =arr1[i-1];
    let bigNum =i;
   /*now looping again and checking if we have any other greater number, if we have one AFTER big number and smaller number to the right. 
     A greater number that is of course greater than that smaller number but smaller than the first number we found.
     Why are doing this? Because that is an algorithm to find next higher number with same digits. 
   */
    for(let j=i+1;j<arr1.length;j++)
      {//What if there are no digits afters those found numbers then of course loop will not be initiated otherwise...
        if(arr1[j]> smlNum && arr1[j]<arr1[i])
        {// we assign that other found number here and replace it with the one we found before
          bigNum=j;

        }
      } //now we are doing swapping of places the small num and big number , 3rd part of alogorithm
    arr1[i-1]=arr1[bigNum];
          arr1[bigNum]=smlNum;
    //returning array 
    //too many functions applied sounds complicated right but no, here is the  trick
    //return arr first then apply each function one by one to see output and then further another func to that output to match your needs
    // so here after swapping , 4th part of alogorithm is to sort the array right after the 1st small num we found
    // to do that first we simple take part of array, we splice it and then we apply sort fucntion, then check output (to check outputs, pls use chrome dev console)
    //and then  simply the rest concat and join to main one digit again.
     return arr1.concat((arr1.splice(i,arr1.length)).sort(function(a, b){return a-b})).join('');



    // Sorry to make it too long but its fun explaining things in much easier ways as much as possible!!
  }

}


findNext(1234);

Since there are lot of comments, so it's better you can copy it to your text editor. Thanks!

pulkit219
  • 77
  • 1
  • 5
0

There are lots of good answers but I didn't find a decent Java implementation. Here is my two cents:

public void findNext(int[] nums) {
    int i = nums.length - 1;
    // nums[i - 1] will be the first non increasing number
    while (i > 0 && nums[i] <= nums[i - 1]) {
        i--;
    }
    if (i == 0) {
        System.out.println("it has been the greatest already");
    } else {
        // Find the smallest digit in the second sequence that is larger than it:
        int j = nums.length - 1;
        while (j >= 0 && nums[j] < nums[i - 1]) {
            j--;
        }
        swap(nums, i - 1, j);
        Arrays.sort(nums, i, nums.length);
        System.out.println(Arrays.toString(nums));
    }
}

public void swap(int[] nums, int i, int j) {
    int tmp = nums[i];
    nums[i] = nums[j];
    nums[j] = tmp;
}
Patrick
  • 2,889
  • 1
  • 24
  • 24
0

This is a more compact answer in Java to this algorithm than this

   public static int permutate2(int number){
        String[] numArray = String.valueOf(number).split("");

        for(int i = numArray.length - 1; i > 0; i--){
            int current = Integer.valueOf(numArray[i]);
            int previous = Integer.valueOf(numArray[i - 1]);

            if(previous < current){
                String[] rest = String.valueOf(number).substring(i, numArray.length).split("");
                Arrays.sort(rest);

                String picker = rest[0];
                int pickerIndex = 0;
                for(int n = 0; n < rest.length ; n++){
                    if(Integer.valueOf(rest[n]) > previous){
                        picker = rest[n];
                        pickerIndex = n;
                        break;
                    }
                }
                numArray[i - 1] = picker;
                rest[pickerIndex] = String.valueOf(previous);
                Arrays.sort(rest);

                String newNumber = "";
                for(int z = 0; z <= i - 1; z++){
                    newNumber += numArray[z];
                }
                for(String z : rest){
                    newNumber += z;
                }

                return Integer.valueOf(newNumber);
            }
        }

        return number;
   }
Bolaji
  • 556
  • 1
  • 6
  • 11
0

Heres a clever solution I did not come up with in C#

 using System;
using System.Linq;

 public static long NextBiggerNumber(long n)
    {        
       String str = GetNumbers(n);
        for (long i = n+1; i <= long.Parse(str); i++)
        {
            if(GetNumbers(n)==GetNumbers(i))
            {
                return i;
            }
        }
        return -1;        
    }
    public static string GetNumbers(long number)
    {
      return string.Join("", number.ToString().ToCharArray().OrderByDescending(x => x));
    }
Leonardo Wildt
  • 2,529
  • 5
  • 27
  • 56
0

Ruby Solution

def next_bigger(num)
  char_array = num.to_s.split('')
  return -1 if char_array.uniq.size == 1

  arr, target_idx, target_char = [], nil, nil
  # get first left-digit less than the right from right side
  (char_array.count - 1).times do |i|
    arr.unshift(char_array[-(i+1)])

    if char_array[-(i+2)] < char_array[-(i+1)]
      target_idx = char_array.count - (i + 2)
      target_char = char_array[-(i+2)]
      arr.unshift(char_array[-(i+2)])
      break
    end
  end
  return -1 unless target_idx

  # first smallest digit larger than target_char to the right
  ((target_char.to_i + 1)..9).to_a.each do |ch|
    if arr.index(ch.to_s)
      flip_char = arr.delete_at(arr.index(ch.to_s))
      # sort the digits to the right of flip_char
      arr.sort!
      # place flip_char to the left of target_char
      arr.unshift(flip_char)
      break
    end
  end

  (char_array[0...target_idx] + arr).join().to_i
end
Piyush Sawaria
  • 121
  • 1
  • 5
0

Implementation in PHP

Time complexity O(n)

$n = "9875";
$n_size = strlen($n);
for($i = $n_size-1; $i > 0; $i-- ) {
     if($n[$i] > $n[$i-1]){
     $temp = $n[$i];
     $n[$i] = $n[$i-1];
     $n[$i-1] = $temp;
     break;
     }
    
}

if($i == 0){
    echo "Next Greater value no possible";
}else{
    echo $n;
}
Amitesh Bharti
  • 14,264
  • 6
  • 62
  • 62
0

I've only tested this with two numbers. They worked. As IT Manager for 8 years until retiring last December, I cared about three things: 1) Accuracy: it's good if it works - always. 2) Speed: has to be acceptable to the user. 3) Clarity: I'm probably not as smart as you are, but I'm paying you. Make sure you explain what you're doing, in English.

Omar, best of luck going forward.

Sub Main()

Dim Base(0 To 9) As Long
Dim Test(0 To 9) As Long

Dim i As Long
Dim j As Long
Dim k As Long
Dim ctr As Long

Const x As Long = 776914648
Dim y As Long
Dim z As Long

Dim flag As Boolean

' Store the digit count for the original number in the Base vector.
    For i = 0 To 9
        ctr = 0
        For j = 1 To Len(CStr(x))
            If Mid$(CStr(x), j, 1) = i Then ctr = ctr + 1
        Next j
        Base(i) = ctr
    Next i

' Start comparing from the next highest number.
    y = x + 1
    Do

' Store the digit count for the each new number in the Test vector.
        flag = False
        For i = 0 To 9
            ctr = 0
            For j = 1 To Len(CStr(y))
                If Mid$(CStr(y), j, 1) = i Then ctr = ctr + 1
            Next j
            Test(i) = ctr
        Next i

' Compare the digit counts.
        For k = 0 To 9
            If Test(k) <> Base(k) Then flag = True
        Next k

' If no match, INC and repeat.
        If flag = True Then
            y = y + 1
            Erase Test()
        Else
            z = y ' Match.
        End If

    Loop Until z > 0

    MsgBox (z), , "Solution"

End Sub
rbanffy
  • 2,319
  • 1
  • 16
  • 27
0

For a nice write-up of how to do this, see "Algorithm L" in Knuth's "The Art of Computer Programming: Generating all Permutations" (.ps.gz).

nibot
  • 14,428
  • 8
  • 54
  • 58
-1
 private static int GetNextHigherNumber(int num)
        {
            //given 38276 return 38627

            string numberstring = num.ToString();

            char[] sNum = numberstring.ToCharArray();

            for (int i = sNum.Length - 1; i > 0; i--)
            {
                for (int j = i - 1; j > 0; j--)
                {
                    if (sNum[i] > sNum[j])
                    {
                        for (int x = i; x > j; x--)
                        {
                            char chr = sNum[x]; 
                            sNum[x] = sNum[x - 1];
                            sNum[x - 1] = chr;
                        }

                        i = 0;
                        break;
                    }
                }
            }

            numberstring = string.Empty;
            for(int x= 0 ; x<sNum.Length;x++)
            {
                numberstring += sNum[x].ToString();
            }

            return Convert.ToInt32(numberstring);
        }
Riaven
  • 121
  • 5
Prashant
  • 11
  • 2
-2

Answer in java with one more condition added

  • Next number should also be an Even number

     public static int nextDigit(int number) {
    String num = String.valueOf(number);
    int stop = 0;
    char[] orig_chars = null;
    char[] part1 = null;
    char[] part2 = null;
    orig_chars = num.toCharArray();
    
    System.out.println("vivek c r");
    for (int i = orig_chars.length - 1; i > 0; i--) {
        String previous = orig_chars[i - 1] + "";
        String next = orig_chars[i] + "";
        if (Integer.parseInt(previous) < Integer.parseInt(next))
    
        {
            if (Integer.parseInt(previous) % 2 == 0) {
    
                String partString1 = "";
                String partString2 = "";
                for (int j = 0; j <= i - 1; j++) {
                    partString1 = partString1.concat(orig_chars[j] + "");
                }
                part1 = partString1.toCharArray();
                for (int k = i; k < orig_chars.length; k++) {
                    partString2 = partString2.concat(orig_chars[k] + "");
                }
                part2 = partString2.toCharArray();
                Arrays.sort(part2);
                for (int l = 0; l < part2.length; l++) {
                    char temp = '0';
                    if (part2[l] > part1[i - 1]) {
                        temp = part1[i - 1];
                        part1[i - 1] = part2[l];
                        part2[l] = temp;
                        break;
                    }
                }
                for (int m = 0; m < part2.length; m++) {
                    char replace = '0';
                    if (part2[m] % 2 == 0) {
                        replace = part2[m];
                        for (int n = m; n < part2.length - 1; n++) {
                            part2[n] = part2[n + 1];
                        }
                        part2[part2.length - 1] = replace;
                        break;
                    }
                }
    
                System.out.print(part1);
                System.out.println(part2);
                System.exit(0);
            }
        }
    }
    System.out.println("NONE");
    
    return 0;
            }
    
Vivek C R
  • 83
  • 1
  • 3
-2
#include <iostream>
using namespace std;

int main ()
{
  int num=15432;
  int quot,rem;
  int numarr[5];
  int length=0;
  while(num!=0)
  {
      rem=num%10;
      num = num/10;
      numarr[length]=rem;
      length++;
  }

 for(int j=0;j<length;j++)
  {
  for(int i=0;i<length;i++)
  {
      if(numarr[i]<numarr[i+1])
      {
          int tmp=numarr[i];
          numarr[i]=numarr[i+1];
          numarr[i+1]=tmp;
      }
  }
  }

  for(int j=0;j<length;j++)
  {
   cout<<numarr[j];
  }
  return 0;
}
-2
import java.util.Scanner;
public class Big {

    public static void main(String[] args) {


        Scanner sc = new Scanner(System.in);
        System.out.print("Enter the number ");
        String str = sc.next();
        int t=0;

        char[] chars  = str.toCharArray();



        for(int i=str.length()-1,j=str.length()-2;j>=0;j--)
        {


                if((int)chars[i]>(int)chars[j])
                {
                    t = (int)chars[i];
                    chars[i] = chars[j];
                    chars[j]=(char)t;

                    for(int k=j+1;k<str.length()-1;k++)
                    {
                        for(int l=k+1;l<str.length();l++)
                        {
                            if(chars[k]>chars[l])
                            {
                                int m = (int)chars[k];
                                chars[k] = chars[l];
                                chars[l]=(char)m;
                            }
                        }
                    }

                    break;
                }






        }
        System.out.print("The next Big number is: ");

        for(int i=0;i<str.length();i++){
            System.out.print(chars[i]);
        }
        sc.close();
    }


}
pfnuesel
  • 14,093
  • 14
  • 58
  • 71
Nithin
  • 1