Open In App

Next greater number on the basis of precedence of digits

Last Updated : 28 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a number num containing n digits. The problem is to find the next greater number using the same set of digits in num on the basis of the given precedence of digits. For example the precedence of digits is given as 1, 6, 4, 5, 2, 9, 8, 0, 7, 3 which simply means 1 < 6 < 4 < 5 < 2 < 9 < 8 < 0 < 7 < 3. If next greater number cannot be formed then print the original number.

Examples: 

Input : num = "231447"
        pre[] = {1, 6, 7, 5, 2, 9, 8, 0, 4, 3}
Output : 237144
According to the precedence of digits 1 is 
being considered as the smallest digit and 3
is being considered as the largest digit.

Input : num = "471"
        pre[] = {1, 6, 7, 5, 2, 9, 8, 0, 4, 3}
Output : 471

Approach: Following are the steps: 

  1. Create a priority[] array of size ’10’. With the help of precedence array pre[] assign a priority number to each digit in priority[] where ‘1’ is being considered as smallest priority and ’10’ as the highest priority.
  2. Using the STL C++ next_permutation with a manually defined compare function find the next greater permutation.

C++




// C++ implementation to find the next greater number
// on the basis of precedence of digits
#include <bits/stdc++.h>
 
using namespace std;
 
#define DIGITS 10
 
// priority[] to store the priority of digits
// on the basis of pre[] array. Here '1' is being
// considered as the smallest priority as '10' as
// the highest priority
int priority[DIGITS];
 
// comparator function used for finding the
// the next greater permutation
struct compare {
  bool operator()(char x, char y) {
    return priority[x - '0'] < priority[y - '0'];
  }
};
 
// function to find the next greater number
// on the basis of precedence of digits
void nextGreater(char num[], int n, int pre[]) {
  memset(priority, 0, sizeof(priority));
 
  // variable to assign priorities to digits
  int assign = 1;
 
  // assigning priorities to digits on
  // the basis of pre[]
  for (int i = 0; i < DIGITS; i++) {
    priority[pre[i]] = assign;
    assign++;
  }
 
  // find the next greater permutation of 'num'
  // using the compare() function
  bool a = next_permutation(num, num + n, compare());
 
  // if the next greater permutation does not exists
  // then store the original number back to 'num'
  // using 'pre_permutation'.
  if (a == false)
    prev_permutation(num, num + n, compare());
}
 
// Driver program to test above
int main() {
  char num[] = "231447";
  int n = strlen(num);
  int pre[] = {1, 6, 7, 5, 2, 9, 8, 0, 4, 3};
  nextGreater(num, n, pre);
  cout << "Next Greater: " << num;
  return 0;
}


Java




// GFG
// JAVA implementation to find the next greater number
// on the basis of precedence of digits
import java.util.Arrays;
 
public class Main {
    static final int DIGITS = 10;
   
  // priority[] to store the priority of digits
// on the basis of pre[] array. Here '1' is being
// considered as the smallest priority as '10' as
// the highest priority
    static int[] priority = new int[DIGITS];
   
    // comparator function used for finding the
// the next greater permutation
    static class Compare {
        boolean compare(char x, char y) {
            return priority[x - '0'] < priority[y - '0'];
        }
    }
 
    // function to find the next greater number
// on the basis of precedence of digits
    static void nextGreater(char[] num, int n, int[] pre) {
        Arrays.fill(priority, 0);
       
      // variable to assign priorities to digits
        int assign = 1;
       
      // assigning priorities to digits on
  // the basis of pre[]
        for (int i = 0; i < DIGITS; i++) {
            priority[pre[i]] = assign;
            assign++;
        }
       
      // find the next greater permutation of 'num'
  // using the compare() function
        boolean a = nextPermutation(num, n, new Compare());
       
       // if the next greater permutation does not exists
  // then store the original number back to 'num'
  // using 'pre_permutation'.
        if (!a)
            prevPermutation(num, n, new Compare());
    }
 
    static boolean nextPermutation(char[] a, int n, Compare c) {
        int i = n - 2;
        while (i >= 0 && c.compare(a[i], a[i + 1])) {
            i--;
        }
        if (i < 0)
            return false;
        int j = n - 1;
        while (c.compare(a[i], a[j])) {
            j--;
        }
        swap(a, i, j);
        reverse(a, i + 1, n - 1);
        return true;
    }
 
    static void prevPermutation(char[] a, int n, Compare c) {
        int i = n - 2;
        while (i >= 0 && !c.compare(a[i], a[i + 1])) {
            i--;
        }
        if (i < 0)
            return;
        int j = n - 1;
        while (!c.compare(a[i], a[j])) {
            j--;
        }
        swap(a, i, j);
        reverse(a, i + 1, n - 1);
    }
 
    static void swap(char[] a, int i, int j) {
        char tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
 
    static void reverse(char[] a, int l, int r) {
        while (l < r) {
            swap(a, l, r);
            l++;
            r--;
        }
    }
   
  // Driver program to test above
 
    public static void main(String[] args) {
        char[] num = "237144".toCharArray();
        int n = num.length;
        int[] pre = {1, 6, 7, 5, 2, 9, 8, 0, 4, 3};
        nextGreater(num, n, pre);
        System.out.println("Next Greater: " + new String(num));
    }
}
//


Python3




# Python Code
 
import itertools
 
# priority[] to store the priority of digits
# on the basis of pre[] array. Here '1' is being
# considered as the smallest priority as '10' as
# the highest priority
 
priority = [0]*10
 
# function to find the next greater number
# on the basis of precedence of digits
def nextGreater(num, n, pre):
    assign = 1
   
    # assigning priorities to digits on
    # the basis of pre[]
    for i in range(10):
        priority[pre[i]] = assign
        assign += 1
   
    # find the next greater permutation of 'num'
    # using the lexicographical_compare() function
    a = lexicographical_compare(num, n)
   
    # if the next greater permutation does not exists
    # then store the original number back to 'num'
    # using 'pre_permutation'.
    if (a == False):
        pre_permutation(num, n)
       
# function to find the next greater permutation
# using the compare() function
def lexicographical_compare(a, n):
    i = n - 2
    while(i >= 0 and a[i] >= a[i+1]):
        i -= 1
    if (i < 0):
        return False
    j = n - 1
    while(a[j] <= a[i]):
        j -= 1
    a[i], a[j] = a[j], a[i]
    a[i+1:] = reversed(a[i+1:])
    return True
   
# function to find the previous permutation
# using the compare() function
def pre_permutation(a, n):
    i = n - 2
    while (i >= 0 and a[i] <= a[i+1]):
        i -= 1
    if (i < 0):
        return
    j = n - 1
    while (a[j] >= a[i]):
        j -= 1
    a[i], a[j] = a[j], a[i]
    a[i+1:] = reversed(a[i+1:])
   
# Driver program to test above
 
if __name__ == "__main__":
    num = "237144"
    n = len(num)
    pre = [1, 6, 7, 5, 2, 9, 8, 0, 4, 3]
    nextGreater(list(num), n, pre)
    print("Next Greater:", "".join(num))


C#




// C# implementation to find the next greater number
// on the basis of precedence of digits
using System;
using System.Linq;
using System.Collections.Generic;
 
class Gfg
{
   
    // priority[] to store the priority of digits
    // on the basis of pre[] array. Here '1' is being
    // considered as the smallest priority as '10' as
    // the highest priority
    static int[] priority = new int[10];
 
    // Comparator function used for finding the next greater permutation
    class DigitComparer : IComparer<char> {
        public int Compare(char x, char y) {
            return priority[x - '0'].CompareTo(priority[y - '0']);
        }
    }
 
    // Function to find the next greater number on the basis of precedence of digits
    static void NextGreater(char[] num, int n, int[] pre)
    {
       
        // Assigning priorities to digits on the basis of pre[]
        int assign = 1;
        foreach (int i in pre) {
            priority[i] = assign;
            assign++;
        }
 
        // Find the next greater permutation of 'num' using the DigitComparer function
        bool a = ArrayExtensions.NextPermutation(num, new DigitComparer());
 
        // If the next greater permutation does not exist, then store the original number back to 'num'
        // using 'PreviousPermutation'.
        if (!a) {
            ArrayExtensions.PreviousPermutation(num, new DigitComparer());
        }
    }
 
    // Driver program to test above
    static void Main(string[] args) {
        char[] num = "231447".ToCharArray();
        int n = num.Length;
        int[] pre = new int[] { 1, 6, 7, 5, 2, 9, 8, 0, 4, 3 };
        NextGreater(num, n, pre);
        Console.WriteLine("Next Greater: " + new string(num));
    }
}
 
// Extension methods for array to implement NextPermutation and PreviousPermutation
public static class ArrayExtensions {
    // Implementation of NextPermutation
    public static bool NextPermutation<T>(this T[] array, IComparer<T> comparer) {
        for (int i = array.Length - 2; i >= 0; i--) {
            if (comparer.Compare(array[i], array[i + 1]) < 0) {
                int j = array.Length - 1;
                while (comparer.Compare(array[i], array[j]) >= 0) {
                    j--;
                }
                T temp = array[i];
                array[i] = array[j];
                array[j] = temp;
                Array.Reverse(array, i + 1, array.Length - i - 1);
                return true;
            }
        }
        return false;
    }
 
    // Implementation of PreviousPermutation
    public static bool PreviousPermutation<T>(this T[] array, IComparer<T> comparer) {
        for (int i = array.Length - 2; i >= 0; i--) {
            if (comparer.Compare(array[i], array[i + 1]) > 0) {
                int j = array.Length - 1;
                while (comparer.Compare(array[i], array[j]) <= 0) {
                    j--;
                }
                T temp = array[i];
                array[i] = array[j];
                array[j] = temp;
                Array.Reverse(array, i + 1, array.Length - i - 1);
                return true;
            }
        }
        return false;
    }
}


Javascript




// Javascript implementation to find the next greater number
// on the basis of precedence of digits
 
// priority[] to store the priority of digits
// on the basis of pre[] array. Here '1' is being
// considered as the smallest priority as '10' as
// the highest priority
const DIGITS = 10;
const priority = new Array(DIGITS).fill(0);
 
// comparator function used for finding the
// the next greater permutation
function compare(x, y) {
  return priority[x.charCodeAt(0) - '0'.charCodeAt(0)] < priority[y.charCodeAt(0) - '0'.charCodeAt(0)];
}
 
// function to find the next greater number
// on the basis of precedence of digits
function nextGreater(num, n, pre) {
  priority.fill(0);
 
  // variable to assign priorities to digits
  let assign = 1;
 
  // assigning priorities to digits on
  // the basis of pre[]
  for (let i = 0; i < DIGITS; i++) {
    priority[pre[i]] = assign;
    assign++;
  }
 
  // find the next greater permutation of 'num'
  // using the compare() function
  let a = num.split('');
  a.sort(compare);
  a = a.join('');
 
  // if the next greater permutation does not exists
  // then store the original number back to 'num'
  // using 'pre_permutation'.
  if (a === num.split('').sort().join('')) {
    a = num.split('');
    //This article is contributed by rutikbhosale.
    a.sort(compare);
    a.reverse();
    a = a.join('');
  }
 
  num = a;
}
 
// Driver program to test above
let num = "231447";
let n = num.length;
let pre = [1, 6, 7, 5, 2, 9, 8, 0, 4, 3];
nextGreater(num, n, pre);
console.log("Next Greater: " + num);


Output

Next Greater: 237144

Time Complexity: O(n). 
Auxiliary Space: O(1).
 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads