Skip to main content
Back to problems
#3551
Medium Algorithms

Minimum swaps to sort by digit sum

Array Hash Table Sorting
50.4% acceptance
Feb 25, 2026
143
5
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.

Solution

Rust
Time O(n²)
Space O(n)
LeetCode
solution.rs
impl Solution {
  pub fn min_swaps(nums: Vec<i32>) -> i32 {
    fn digit_sum(mut x: i32) -> i32 {
      let mut s = 0;
      while x > 0 { s += x % 10; x /= 10; }
      s
    }
    let n = nums.len();
    // Build sorted target
    let mut sorted = nums.clone();
    sorted.sort_by(|&a, &b| digit_sum(a).cmp(&digit_sum(b)).then(a.cmp(&b)));
    // For each value in nums, find its target index
    // Build position map: value -> target index
    use std::collections::HashMap;
    let mut pos: HashMap<i32, usize> = HashMap::new();
    for (i, &v) in sorted.iter().enumerate() { pos.insert(v, i); }
    // Count cycles in permutation
    let perm: Vec<usize> = nums.iter().map(|v| pos[v]).collect();
    let mut visited = vec![false; n];
    let mut swaps = 0;
    for i in 0..n {
      if visited[i] || perm[i] == i { visited[i] = true; continue; }
      let mut cycle_len = 0;
      let mut j = i;
      while !visited[j] {
        visited[j] = true;
        j = perm[j];
        cycle_len += 1;
      }
      swaps += cycle_len - 1;
    }
    swaps
  }
}