3551. Minimum Swaps to Sort by Digit Sum
Description
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:
- Compute the digit sum for each integer:
[3 + 7 = 10, 1 + 0 + 0 = 1] → [10, 1]
- Sort the integers based on digit sum:
[100, 37]
. Swap37
with100
to obtain the sorted order. - Thus, the minimum number of swaps required to rearrange
nums
is 1.
Example 2:
Input: nums = [22,14,33,7]
Output: 0
Explanation:
- Compute the digit sum for each integer:
[2 + 2 = 4, 1 + 4 = 5, 3 + 3 = 6, 7 = 7] → [4, 5, 6, 7]
- Sort the integers based on digit sum:
[22, 14, 33, 7]
. The array is already sorted. - Thus, the minimum number of swaps required to rearrange
nums
is 0.
Example 3:
Input: nums = [18,43,34,16]
Output: 2
Explanation:
- Compute the digit sum for each integer:
[1 + 8 = 9, 4 + 3 = 7, 3 + 4 = 7, 1 + 6 = 7] → [9, 7, 7, 7]
- Sort the integers based on digit sum:
[16, 34, 43, 18]
. Swap18
with16
, and swap43
with34
to obtain the sorted order. - Thus, the minimum number of swaps required to rearrange
nums
is 2.
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 109
nums
consists of distinct positive integers.
Solutions
Solution 1
Python3
class Solution:
def minSwaps(self, nums: List[int]) -> int:
def f(x: int) -> int:
s = 0
while x:
s += x % 10
x //= 10
return s
n = len(nums)
arr = sorted((f(x), x) for x in nums)
d = {a[1]: i for i, a in enumerate(arr)}
ans = n
vis = [False] * n
for i in range(n):
if not vis[i]:
ans -= 1
j = i
while not vis[j]:
vis[j] = True
j = d[nums[j]]
return ans
Java
class Solution {
public int minSwaps(int[] nums) {
int n = nums.length;
int[][] arr = new int[n][2];
for (int i = 0; i < n; i++) {
arr[i][0] = f(nums[i]);
arr[i][1] = nums[i];
}
Arrays.sort(arr, (a, b) -> {
if (a[0] != b[0]) return Integer.compare(a[0], b[0]);
return Integer.compare(a[1], b[1]);
});
Map<Integer, Integer> d = new HashMap<>();
for (int i = 0; i < n; i++) {
d.put(arr[i][1], i);
}
boolean[] vis = new boolean[n];
int ans = n;
for (int i = 0; i < n; i++) {
if (!vis[i]) {
ans--;
int j = i;
while (!vis[j]) {
vis[j] = true;
j = d.get(nums[j]);
}
}
}
return ans;
}
private int f(int x) {
int s = 0;
while (x != 0) {
s += x % 10;
x /= 10;
}
return s;
}
}
C++
class Solution {
public:
int f(int x) {
int s = 0;
while (x) {
s += x % 10;
x /= 10;
}
return s;
}
int minSwaps(vector<int>& nums) {
int n = nums.size();
vector<pair<int, int>> arr(n);
for (int i = 0; i < n; ++i) arr[i] = {f(nums[i]), nums[i]};
sort(arr.begin(), arr.end());
unordered_map<int, int> d;
for (int i = 0; i < n; ++i) d[arr[i].second] = i;
vector<char> vis(n, 0);
int ans = n;
for (int i = 0; i < n; ++i) {
if (!vis[i]) {
--ans;
int j = i;
while (!vis[j]) {
vis[j] = 1;
j = d[nums[j]];
}
}
}
return ans;
}
};
Go
func minSwaps(nums []int) int {
n := len(nums)
arr := make([][2]int, n)
for i := 0; i < n; i++ {
arr[i][0] = f(nums[i])
arr[i][1] = nums[i]
}
sort.Slice(arr, func(i, j int) bool {
if arr[i][0] != arr[j][0] {
return arr[i][0] < arr[j][0]
}
return arr[i][1] < arr[j][1]
})
d := make(map[int]int, n)
for i := 0; i < n; i++ {
d[arr[i][1]] = i
}
vis := make([]bool, n)
ans := n
for i := 0; i < n; i++ {
if !vis[i] {
ans--
j := i
for !vis[j] {
vis[j] = true
j = d[nums[j]]
}
}
}
return ans
}
func f(x int) int {
s := 0
for x != 0 {
s += x % 10
x /= 10
}
return s
}
TypeScript
function f(x: number): number {
let s = 0;
while (x !== 0) {
s += x % 10;
x = Math.floor(x / 10);
}
return s;
}
function minSwaps(nums: number[]): number {
const n = nums.length;
const arr: [number, number][] = new Array(n);
for (let i = 0; i < n; i++) {
arr[i] = [f(nums[i]), nums[i]];
}
arr.sort((a, b) => (a[0] !== b[0] ? a[0] - b[0] : a[1] - b[1]));
const d = new Map<number, number>();
for (let i = 0; i < n; i++) {
d.set(arr[i][1], i);
}
const vis: boolean[] = new Array(n).fill(false);
let ans = n;
for (let i = 0; i < n; i++) {
if (!vis[i]) {
ans--;
let j = i;
while (!vis[j]) {
vis[j] = true;
j = d.get(nums[j])!;
}
}
}
return ans;
}