LeetCode-in-Java

3551. Minimum Swaps to Sort by Digit Sum

Medium

You are given an array nums of distinct positive integers. You need to sort the array in increasing order based on the sum of the digits of each number. If two numbers have the same digit sum, the smaller number appears first in the sorted order.

Return the minimum number of swaps required to rearrange nums into this sorted order.

A swap is defined as exchanging the values at two distinct positions in the array.

Example 1:

Input: nums = [37,100]

Output: 1

Explanation:

Example 2:

Input: nums = [22,14,33,7]

Output: 0

Explanation:

Example 3:

Input: nums = [18,43,34,16]

Output: 2

Explanation:

Constraints:

Solution

import java.util.Arrays;

public class Solution {
    private static class Pair {
        int sum;
        int value;
        int index;

        Pair(int s, int v, int i) {
            sum = s;
            value = v;
            index = i;
        }
    }

    public int minSwaps(int[] arr) {
        int n = arr.length;
        Pair[] pairs = new Pair[n];
        for (int i = 0; i < n; i++) {
            int v = arr[i];
            int s = 0;
            while (v > 0) {
                s += v % 10;
                v /= 10;
            }
            pairs[i] = new Pair(s, arr[i], i);
        }
        Arrays.sort(
                pairs,
                (a, b) -> {
                    if (a.sum != b.sum) {
                        return a.sum - b.sum;
                    }
                    return a.value - b.value;
                });
        int[] posMap = new int[n];
        for (int i = 0; i < n; i++) {
            posMap[i] = pairs[i].index;
        }
        boolean[] seen = new boolean[n];
        int swaps = 0;
        for (int i = 0; i < n; i++) {
            if (seen[i] || posMap[i] == i) {
                continue;
            }
            int cycleSize = 0;
            int j = i;
            while (!seen[j]) {
                seen[j] = true;
                j = posMap[j];
                cycleSize++;
            }
            swaps += cycleSize - 1;
        }
        return swaps;
    }
}