Task is to find the next greater number that has same digits.
So, here are some samples:
Input: n = "218765"
Output: "251678"
Input: n = "1234"
Output: "1243"
Input: n = "4321"
Output: "Not Possible"
Input: n = "534976"
Output: "536479"
Samples were taken from geeks for geeks
def next_bigger(n):
if len(str(n)) == 1:
return -1
else:
pass
k = math.factorial(len(str(n)))
lst2 = []
lst3 = []
lst4 = []
for num in str(n):
lst2.append(num)
for num in lst2:
if lst2.count(num) == len(lst2):
return -1
else:
pass
for num in lst2:
if lst2.count(num) > 1 and num not in lst4:
k = k/math.factorial(lst2.count(num))
lst4.append(num)
else:
pass
while True:
shuffle(lst2)
if int(''.join(lst2)) not in lst3:
lst3.append(int(''.join(lst2)))
print(len(lst3))
pass
if int(''.join(lst2)) in lst3:
if len(lst3) == k:
break
else:
pass
t = sorted(lst3)
for num in t:
if num > n:
return num
else:
pass
return -1
My code seems to work, but it runs into timeout. First, code checks for corner solutions like n = 1111
or n = 3
Second, it uses combinatorics to determine how many combinations are available to get from the given number. Third, it shuffles numbers to get all available combinations and adds them to the list. From there it just gets the next number from the given one or returns -1.
It seem to work with all samples.
Is it possible to somehow optimize this way of solving this problem ?
With Python everything is possible :)
you can do something like this
def next_greater_number(n):
n_s = str(n)
N = len(n_s)
min_digit = int(n_s[-1])
min_digit_idx = N-1
left_side = n_s
right_side = ''
for i in range(len(n_s)-1, 0, -1):
left_side = left_side[:i]
right_side = n_s[i] + right_side
# print(left_side, right_side)
# keep record of minimum number
if int(n_s[i]) < min_digit:
min_digit_idx = i
min_digit = int(n_s[i])
# get to the point where right digit is greater than left digit
if int(n_s[i]) > int(n_s[i-1]):
# exclude min digit, because we will append it on the left side
right_side = n_s[i:min_digit_idx] + n_s[min_digit_idx+1:] + left_side[-1]
right_side = ''.join(sorted(right_side))
output = left_side[:-1] + str(min_digit) + right_side
break
else:
output = "Not Possible"
return output
By traversing right to left looking for a pattern where right side digit is greater than the left digit. We need to replace minimum of the right side with left side last digit. After that sorting the right side makes number just greater than current number.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.