Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Previous Permutation With One Swap in Python
Finding the previous permutation with one swap means finding the lexicographically largest permutation that is smaller than the given array by swapping exactly two elements. If no such permutation exists, we return the original array.
For example, given [3,2,1], we can swap positions 1 and 2 to get [3,1,2], which is the largest permutation smaller than the original.
Algorithm
The algorithm follows these steps ?
- Find the rightmost position where
A[left] > A[left + 1] - If no such position exists, return the original array
- Find the largest element to the right of
leftthat is smaller thanA[left] - Swap these two elements
Implementation
def prevPermOpt1(A):
n = len(A)
# Find the rightmost position where A[left] > A[left + 1]
left = -1
for i in range(n - 2, -1, -1):
if A[i] > A[i + 1]:
left = i
break
# If no such position exists, return original array
if left == -1:
return A
# Find the largest element smaller than A[left]
max_element = 0
swap_index = -1
for right in range(left + 1, n):
if A[right] < A[left] and A[right] > max_element:
max_element = A[right]
swap_index = right
# Swap the elements
A[left], A[swap_index] = A[swap_index], A[left]
return A
# Test with examples
print("Example 1:", prevPermOpt1([4, 2, 3, 1, 3]))
print("Example 2:", prevPermOpt1([3, 2, 1]))
print("Example 3:", prevPermOpt1([1, 2, 3]))
Example 1: [4, 2, 1, 3, 3] Example 2: [3, 1, 2] Example 3: [1, 2, 3]
How It Works
Let's trace through the algorithm with [4, 2, 3, 1, 3] ?
-
Find the pivot: Starting from right, we find
A[1] = 2 > A[2] = 3is false, butA[0] = 4 > A[1] = 2is true, soleft = 0 -
Find swap candidate: Look for the largest element smaller than
A[0] = 4in positions 1-4. We findA[3] = 1is the largest valid candidate -
Swap: Exchange
A[0]andA[3]to get[1, 2, 3, 4, 3]
Edge Cases
The algorithm handles several edge cases ?
# Already smallest permutation
print("Already smallest:", prevPermOpt1([1, 2, 3, 4]))
# Single element
print("Single element:", prevPermOpt1([5]))
# All elements same
print("All same:", prevPermOpt1([2, 2, 2]))
Already smallest: [1, 2, 3, 4] Single element: [5] All same: [2, 2, 2]
Time Complexity
The algorithm has O(n) time complexity since we make at most two passes through the array. The space complexity is O(1) as we only use a constant amount of extra space.
Conclusion
The previous permutation algorithm finds the lexicographically largest permutation smaller than the input by identifying the rightmost "break point" and swapping with the optimal candidate. This approach efficiently handles all edge cases in linear time.
---