Minimum Number of Operations to Sort Binary Tree by Level

Sanjeev SharmaSanjeev Sharma
3 min read

Advertisement

Problem

Each operation swaps two nodes on the same level. Return minimum total swaps to make each level sorted.

Key insight: For each level, minimum swaps to sort = (length - number of cycles in permutation). Use coordinate compression.

Solutions

# Python
from collections import deque

def minimumOperations(root):
    def min_swaps(arr):
        # min swaps to sort = n - num_cycles
        n = len(arr)
        indexed = sorted(range(n), key=lambda i: arr[i])
        visited = [False] * n
        cycles = 0
        for i in range(n):
            if visited[i] or indexed[i] == i:
                if not visited[i]:
                    cycles += 1
                    visited[i] = True
                continue
            cycle_len = 0
            j = i
            while not visited[j]:
                visited[j] = True
                j = indexed[j]
                cycle_len += 1
            cycles += 1
        return n - cycles

    total = 0
    q = deque([root])
    while q:
        level = []
        for _ in range(len(q)):
            node = q.popleft()
            level.append(node.val)
            if node.left:  q.append(node.left)
            if node.right: q.append(node.right)
        total += min_swaps(level)
    return total
// C++
int minSwaps(vector<int>& arr) {
    int n = arr.size();
    vector<int> idx(n);
    iota(idx.begin(), idx.end(), 0);
    sort(idx.begin(), idx.end(), [&](int a, int b){ return arr[a] < arr[b]; });
    vector<bool> vis(n, false);
    int cycles = 0;
    for (int i = 0; i < n; i++) {
        if (vis[i] || idx[i] == i) { if(!vis[i]){cycles++;vis[i]=true;} continue; }
        int j = i;
        while (!vis[j]) { vis[j] = true; j = idx[j]; }
        cycles++;
    }
    return n - cycles;
}
int minimumOperations(TreeNode* root) {
    queue<TreeNode*> q;
    q.push(root);
    int total = 0;
    while (!q.empty()) {
        int sz = q.size();
        vector<int> level;
        while (sz--) {
            auto node = q.front(); q.pop();
            level.push_back(node->val);
            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
        total += minSwaps(level);
    }
    return total;
}
// Java
int minSwaps(int[] arr) {
    int n = arr.length;
    Integer[] idx = new Integer[n];
    for (int i = 0; i < n; i++) idx[i] = i;
    Arrays.sort(idx, (a, b) -> arr[a] - arr[b]);
    boolean[] vis = new boolean[n];
    int cycles = 0;
    for (int i = 0; i < n; i++) {
        if (vis[i] || idx[i] == i) { if (!vis[i]) { cycles++; vis[i] = true; } continue; }
        int j = i;
        while (!vis[j]) { vis[j] = true; j = idx[j]; }
        cycles++;
    }
    return n - cycles;
}
public int minimumOperations(TreeNode root) {
    Queue<TreeNode> q = new LinkedList<>();
    q.add(root);
    int total = 0;
    while (!q.isEmpty()) {
        int sz = q.size();
        int[] level = new int[sz];
        for (int i = 0; i < sz; i++) {
            TreeNode node = q.poll();
            level[i] = node.val;
            if (node.left != null) q.add(node.left);
            if (node.right != null) q.add(node.right);
        }
        total += minSwaps(level);
    }
    return total;
}
// JavaScript
function minimumOperations(root) {
    function minSwaps(arr) {
        const n = arr.length;
        const idx = [...Array(n).keys()].sort((a, b) => arr[a] - arr[b]);
        const vis = Array(n).fill(false);
        let cycles = 0;
        for (let i = 0; i < n; i++) {
            if (vis[i] || idx[i] === i) { if (!vis[i]) { cycles++; vis[i] = true; } continue; }
            let j = i;
            while (!vis[j]) { vis[j] = true; j = idx[j]; }
            cycles++;
        }
        return n - cycles;
    }
    let queue = [root], total = 0;
    while (queue.length) {
        total += minSwaps(queue.map(n => n.val));
        queue = queue.flatMap(n => [n.left, n.right].filter(Boolean));
    }
    return total;
}

Complexity

  • Time: O(n log n)
  • Space: O(n)

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro