Welcome to Subscribe On Youtube

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]. Swap 37 with 100 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]. Swap 18 with 16, and swap 43 with 34 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

  • 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;
        }
    }
    
    
  • 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;
        }
    };
    
    
  • 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
    
    
  • 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
    }
    
  • 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;
    }
    
    
  • function f(x) {
        let s = 0;
        while (x !== 0) {
            s += x % 10;
            x = Math.floor(x / 10);
        }
        return s;
    }
    
    /**
     * @param {number[]} nums
     * @return {number}
     */
    var minSwaps = function (nums) {
        const n = nums.length;
        const arr = 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();
        for (let i = 0; i < n; i++) {
            d.set(arr[i][1], i);
        }
        const vis = 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;
    };
    
    
  • class Solution {
        /**
         * @param Integer[] $nums
         * @return Integer
         */
        function minSwaps($nums) {
            $n = count($nums);
            $arr = [];
            foreach ($nums as $x) {
                $arr[] = [$this->f($x), $x];
            }
            usort($arr, function ($a, $b) {
                if ($a[0] != $b[0]) {
                    return $a[0] <=> $b[0];
                }
                return $a[1] <=> $b[1];
            });
            $d = [];
            for ($i = 0; $i < $n; $i++) {
                $d[$arr[$i][1]] = $i;
            }
            $vis = array_fill(0, $n, false);
            $ans = $n;
            for ($i = 0; $i < $n; $i++) {
                if (!$vis[$i]) {
                    $ans--;
                    $j = $i;
                    while (!$vis[$j]) {
                        $vis[$j] = true;
                        $j = $d[$nums[$j]];
                    }
                }
            }
            return $ans;
        }
    
        private function f($x) {
            $s = 0;
            while ($x != 0) {
                $s += $x % 10;
                $x = intdiv($x, 10);
            }
            return $s;
        }
    }
    
    
  • public class Solution {
        public int MinSwaps(int[] nums) {
            int n = nums.Length;
            int[][] arr = new int[n][];
            for (int i = 0; i < n; i++) {
                arr[i] = new int[] { F(nums[i]), nums[i] };
            }
            Array.Sort(arr, (a, b) => {
                if (a[0] != b[0]) {
                    return a[0].CompareTo(b[0]);
                }
                return a[1].CompareTo(b[1]);
            });
            Dictionary<int, int> d = new Dictionary<int, int>();
            for (int i = 0; i < n; i++) {
                d[arr[i][1]] = i;
            }
            bool[] vis = new bool[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[nums[j]];
                    }
                }
            }
            return ans;
        }
    
        private int F(int x) {
            int s = 0;
            while (x != 0) {
                s += x % 10;
                x /= 10;
            }
            return s;
        }
    }
    
    
  • use std::collections::HashMap;
    
    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();
            let mut arr: Vec<(i32, i32)> = nums.iter().map(|&x| (digit_sum(x), x)).collect();
            arr.sort();
            let mut d = HashMap::new();
            for (i, &(_, x)) in arr.iter().enumerate() {
                d.insert(x, i);
            }
            let mut vis = vec![false; n];
            let mut ans = n as i32;
            for i in 0..n {
                if !vis[i] {
                    ans -= 1;
                    let mut j = i;
                    while !vis[j] {
                        vis[j] = true;
                        j = d[&nums[j]];
                    }
                }
            }
            ans
        }
    }
    
    

All Problems

All Solutions