Monday, 26 January 2015

Find next greatest number from digits of a given number

Find the smallest number that has same set of digits as n and is greater than n. 
If n is the greatest possible number with its set of digits, then print "not possible".

Examples:

Input:  n = "1234"
Output: "1243"

Input:  n = "1243"
Output: "1324"

Input:  n = "1324"
Output: "1342"

Input:  n = "1342"
Output: "1423"

Input: n = "4321"

Output: "Not Possible"

Input:  n = "5349762"
Output: "5362479"

Input: n = "53497766"
Output: "53646779"


Algorithm:

From the first few examples, we can see that the algorithm is to traverse the given number from rightmost digit, keep traversing till you find a digit which is smaller than the previously traversed digit. Then replace this small number with the next highest traversed number. Then pick remaining traversed number plus the small number, sort them from smallest to largest and append them to the end. 


package com.prasune.coding;

import java.util.Set;
import java.util.TreeSet;

public class NextGreatestNumber {

      public static void main(String[] args) {
            printNextGreaterNumber(4321);
      }

      private static void printNextGreaterNumber(Integer number) {
            String nextGreaterNumber = null;
            String numberAsString = number.toString();
            Integer prevValue = 0;
            Set<Integer> numbersToSort =
                  new TreeSet<Integer>(new CustomComparator());        
           
            for (int i = numberAsString.length() - 1; 0 <= i; i--) {
                  Integer digit =                   Integer.parseInt(""+numberAsString.charAt(i));             
                  if(digit < prevValue){
                        Integer replacement = 
                                   getReplacementNumber(digit, numbersToSort);

                        nextGreaterNumber = numberAsString.substring(0, i)
                                          + replacement;
                        numbersToSort.add(digit);
                        nextGreaterNumber = appendSortedNumbers(
                                              nextGreaterNumber,                                                              numbersToSort,                                                                  replacement);
                        break;
                  } else{
                        prevValue = digit;
                  }    
                  numbersToSort.add(digit);
            }
            if(nextGreaterNumber != null){
                  System.out.println("Next greater number: " 
                                     + nextGreaterNumber);
            }else{
                  System.out.println("Not Possible");
            }          
      }

      private static Integer getReplacementNumber(Integer digit,                                                                  Set<Integer> numbersToSort) {
            Integer replacementNumber = 0;
            for (Integer number : numbersToSort) {
                  if(number > digit){
                        replacementNumber = number;
                        break;
                  }
            }
            return replacementNumber;
      }

      private static String appendSortedNumbers(String nextGreaterNumber,
                                                Set<Integer> numbersToSort,
                                                Integer replacement) {
            boolean isReplacementExcluded = false;
            StringBuilder greaterNumberString =
                                      new StringBuilder(nextGreaterNumber);
            for (Integer number : numbersToSort) {
                  if(!isReplacementExcluded && number == replacement){
                        isReplacementExcluded = true;                  
                  }else {
                        greaterNumberString.append(number);
                  }
            }
            return greaterNumberString.toString();
      }    
}