Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1806. Minimum Number of Operations to Reinitialize a Permutation - Leetcode Solution

Problem Description

Given an even integer n, you start with a permutation perm of length n where perm[i] = i for 0 ≤ i < n. You then perform the following operation repeatedly to generate a new array arr from perm:

  • If i is even, then arr[i] = perm[i / 2]
  • If i is odd, then arr[i] = perm[n / 2 + (i - 1) / 2]

After each operation, perm becomes arr. The task is to determine the minimum number of operations required to return perm back to its original order (that is, perm[i] = i for all i).

Constraints:

  • 2 ≤ n ≤ 1000
  • n is even

Thought Process

At first glance, the problem seems to require simulating the permutation repeatedly until it cycles back to the starting order. A brute-force approach would be to keep applying the operation, checking after each step whether the array has returned to its original state.

However, because n can be as large as 1000, simulating the entire array for each operation could be inefficient. We should look for patterns or properties in the way elements are shuffled to optimize our solution.

Notably, the operation is a deterministic mapping: each index moves to a new position based on whether it's even or odd. This hints at a possible cycle structure or mathematical pattern that can be exploited.

Solution Approach

Let's break down the steps to solve the problem efficiently:

  1. Track the Position of a Single Index:
    • Since the operation is deterministic and the permutation is restored when all elements return to their original positions, we can focus on tracking how long it takes for a single index (say, index 1) to return to its original position.
    • The reason this works is that the mapping forms cycles, and the permutation as a whole will return to the starting order when all cycles have completed a full rotation. For this specific permutation operation, it turns out that all cycles have the same length, so tracking one is sufficient.
  2. Simulate the Mapping for One Index:
    • Start with pos = 1.
    • Apply the mapping rules:
      • If pos is even, new pos = pos / 2
      • If pos is odd, new pos = n / 2 + (pos - 1) / 2
    • Continue until pos returns to 1, counting the number of steps taken.
  3. Return the Step Count:
    • The number of steps needed for index 1 to return to its original position is the answer.

This approach is efficient because it avoids simulating the entire array and only tracks one index through its cycle.

Example Walkthrough

Let's walk through the process for n = 6:

  • Start with perm = [0,1,2,3,4,5]
  • Track pos = 1 (the index of value 1)
  • Step 1:
    pos = 1 is odd ⇒ pos = 6/2 + (1-1)/2 = 3
  • Step 2:
    pos = 3 is odd ⇒ pos = 6/2 + (3-1)/2 = 4
  • Step 3:
    pos = 4 is even ⇒ pos = 4/2 = 2
  • Step 4:
    pos = 2 is even ⇒ pos = 2/2 = 1
  • Result: It takes 4 steps for index 1 to return to its original position. So the answer is 4.

Time and Space Complexity

  • Brute-force Approach: Simulating the entire array each step would take O(n) per operation, and up to O(n) operations, leading to O(n^2) time and O(n) space.
  • Optimized Approach: By tracking only one index, each operation is O(1), and in the worst case, we do up to O(n) operations (since the cycle length can be up to n-1). Thus, overall time complexity is O(n) and space complexity is O(1).

Summary

The key insight is to realize that the permutation operation forms cycles, and the permutation is restored when all cycles complete. By tracking the position of a single element (like index 1), we can efficiently compute the minimum number of operations needed without simulating the entire array. This approach is both elegant and efficient, reducing the problem to simple arithmetic operations and a single loop.

Code Implementation

class Solution:
    def reinitializePermutation(self, n: int) -> int:
        pos = 1
        steps = 0
        while True:
            if pos % 2 == 0:
                pos = pos // 2
            else:
                pos = n // 2 + (pos - 1) // 2
            steps += 1
            if pos == 1:
                return steps
      
class Solution {
public:
    int reinitializePermutation(int n) {
        int pos = 1;
        int steps = 0;
        do {
            if (pos % 2 == 0)
                pos = pos / 2;
            else
                pos = n / 2 + (pos - 1) / 2;
            steps++;
        } while (pos != 1);
        return steps;
    }
};
      
class Solution {
    public int reinitializePermutation(int n) {
        int pos = 1, steps = 0;
        do {
            if (pos % 2 == 0)
                pos = pos / 2;
            else
                pos = n / 2 + (pos - 1) / 2;
            steps++;
        } while (pos != 1);
        return steps;
    }
}
      
var reinitializePermutation = function(n) {
    let pos = 1, steps = 0;
    do {
        if (pos % 2 === 0)
            pos = pos / 2;
        else
            pos = Math.floor(n / 2 + (pos - 1) / 2);
        steps++;
    } while (pos !== 1);
    return steps;
};