Given a positive integer n, find the smallest integer that is greater than n and contains exactly the same digits as n. In other words, find the next lexicographic permutation of the digits in n.
If no such integer exists (because n is already the largest permutation of its digits), or if the result would exceed the 32-bit signed integer maximum value (2³¹ - 1 = 2,147,483,647), return -1.
-1 if no valid permutation exists-1 if the result exceeds 2,147,483,647Example 1:
Input: n = 12 Output: 21 Explanation: The only greater permutation of digits 1 and 2 is 21.
Example 2:
Input: n = 230241 Output: 230412 Explanation: Starting from the right, we find that 2 (at position 3 from left) is the first digit smaller than its successor. We swap it with 4 (the smallest digit greater than 2 in the suffix), giving 230421. Then we reverse the suffix after position 3 to get 230412.
Example 3:
Input: n = 321 Output: -1 Explanation: The digits are in descending order, so this is already the largest permutation possible.
Example 4:
Input: n = 1 Output: -1 Explanation: A single digit has no other permutation.
Hint 1: Finding the Pivot To find the next permutation, scan from right to left to find the first digit that is smaller than the digit to its right. This is your "pivot" position. If no such digit exists, the number is already at its maximum permutation.
Hint 2: Swapping Strategy Once you've found the pivot, you need to swap it with the smallest digit to its right that is still larger than the pivot. After swapping, the suffix to the right of the pivot position should be arranged in ascending order to ensure the result is the smallest possible greater number.
Hint 3: Optimization After swapping, notice that the suffix is still in descending order (because we found the rightmost position to swap). You can simply reverse this suffix instead of sorting it, which takes O(d) time instead of O(d log d).
Full Solution `` Explanation:
The algorithm implements the standard next permutation procedure:
- Find the pivot: Scan from right to left to find the first position where a digit is smaller than its right neighbor. This marks the position where we need to make a change. If no such position exists, the digits are in descending order and we're already at the maximum permutation.
- Find the swap candidate: Among all digits to the right of the pivot, find the smallest one that is still larger than the pivot digit. Due to the descending order of the suffix, this is simply the rightmost digit greater than the pivot.
- Swap: Exchange the pivot with the swap candidate.
- Minimize the suffix: After swapping, the suffix (everything after the pivot position) is still in descending order. Reverse it to make it ascending, which gives us the smallest possible arrangement.
- Boundary check: Verify the result doesn't exceed the 32-bit integer limit.
Time Complexity: O(d) where d is the number of digits in n. We make at most three passes through the digits.
Space Complexity: O(d) for storing the digit array.
def nextGreaterElement(n: int) -> int:
# Convert number to list of digits for easier manipulation
digits = list(str(n))
length = len(digits)
# Step 1: Find the rightmost digit that is smaller than its successor
# This is the pivot position
pivot = -1
for i in range(length - 2, -1, -1):
if digits[i] < digits[i + 1]:
pivot = i
break
# If no pivot found, number is already at maximum permutation
if pivot == -1:
return -1
# Step 2: Find the smallest digit to the right of pivot that is larger than pivot
# Since digits to the right of pivot are in descending order,
# we scan from right to find the rightmost digit greater than pivot
swap_idx = -1
for i in range(length - 1, pivot, -1):
if digits[i] > digits[pivot]:
swap_idx = i
break
# Step 3: Swap pivot with the found digit
digits[pivot], digits[swap_idx] = digits[swap_idx], digits[pivot]
# Step 4: Reverse the suffix after pivot to get the smallest permutation
# The suffix is currently in descending order, so reversing makes it ascending
digits[pivot + 1:] = reversed(digits[pivot + 1:])
# Convert back to integer
result = int(''.join(digits))
# Check if result exceeds 32-bit signed integer limit
if result > 2**31 - 1:
return -1
return result