string
]
Leetcode 0556. Next Greater Element III
https://leetcode.com/problems/next-greater-element-iii
Let us start from example and see how our algorithm should work.
Imaigne n = 234157641
. Our goal is to find next number with the same digits, which is greater than given one and which is the smallest one. It makes sense to try to take our number as close to original one as possible. Let us try to do it: can it start from 2......
, yes, for example 24...
. Can it start with 2341...
? Yes, it can be 23417...
. Can it start with 23415...
? No, it can not, and the reason, that the rest what we have 7641
already biggest number given digits 7, 6, 4, 1
.
So, we can see now, how our algorithm should work:
- Start from the end and look for increasing pattern, it our case
7641
. - If it happen, that all number has increasing pattern, there is no bigger number with the same digits, so we can return
-1
. - Now, we need to find the first digit in our ending, which is less or equal to
digits[i-1]
: we have ending5 7641
and we are looking for the next number with the same digits. What can go instead of5
: it is6
! Let us change these two digits, so we have6 7541
now. Finally, we need to reverse last ditits to get6 1457
as our ending.
Complexity: time complexity is O(m)
, where m
is number of digits in our number, space complexity O(m)
as well.
PS see also problem 31. Next Permutation, which uses exactly the same idea.
class Solution:
def nextGreaterElement(self, n):
digits = list(str(n))
i = len(digits) - 1
while i-1 >= 0 and digits[i] <= digits[i-1]:
i -= 1
if i == 0: return -1
j = i
while j+1 < len(digits) and digits[j+1] > digits[i-1]:
j += 1
digits[i-1], digits[j] = digits[j], digits[i-1]
digits[i:] = digits[i:][::-1]
ret = int(''.join(digits))
return ret if ret < 1<<31 else -1
If you like the solution, you can upvote it on leetcode discussion section: Problem 0556