Previous Permutation With One Swap

medium greedy array permutation

Problem

Given an array of positive integers arr (not necessarily distinct), return the lexicographically largest permutation that is smaller than arr, that can be made with exactly one swap. If it cannot be done, then return the same array.

Inputarr = [3, 2, 1]
Output[3, 1, 2]
Swapping 2 and 1 gives the largest array still smaller than [3, 2, 1].

def prev_perm_opt1(arr):
    n = len(arr)
    for i in range(n - 2, -1, -1):
        if arr[i] > arr[i + 1]:
            j = i + 1
            while j + 1 < n and arr[j + 1] < arr[i]:
                j += 1
            while j > i + 1 and arr[j] == arr[j - 1]:
                j -= 1
            arr[i], arr[j] = arr[j], arr[i]
            break
    return arr
function prevPermOpt1(arr) {
  const n = arr.length;
  for (let i = n - 2; i >= 0; i--) {
    if (arr[i] > arr[i + 1]) {
      let j = i + 1;
      while (j + 1 < n && arr[j + 1] < arr[i]) j++;
      while (j > i + 1 && arr[j] === arr[j - 1]) j--;
      [arr[i], arr[j]] = [arr[j], arr[i]];
      break;
    }
  }
  return arr;
}
class Solution {
    public int[] prevPermOpt1(int[] arr) {
        int n = arr.length;
        for (int i = n - 2; i >= 0; i--) {
            if (arr[i] > arr[i + 1]) {
                int j = i + 1;
                while (j + 1 < n && arr[j + 1] < arr[i]) j++;
                while (j > i + 1 && arr[j] == arr[j - 1]) j--;
                int t = arr[i]; arr[i] = arr[j]; arr[j] = t;
                break;
            }
        }
        return arr;
    }
}
vector<int> prevPermOpt1(vector<int>& arr) {
    int n = arr.size();
    for (int i = n - 2; i >= 0; i--) {
        if (arr[i] > arr[i + 1]) {
            int j = i + 1;
            while (j + 1 < n && arr[j + 1] < arr[i]) j++;
            while (j > i + 1 && arr[j] == arr[j - 1]) j--;
            swap(arr[i], arr[j]);
            break;
        }
    }
    return arr;
}
Time: O(n) Space: O(1)