Problem Link

Description


You are given an array of positive integers nums and a positive integer k.

A permutation of nums is said to form a divisible concatenation if, when you concatenate the decimal representations of the numbers in the order specified by the permutation, the resulting number is divisible by k.

Return the lexicographically smallest permutation (when considered as a list of integers) that forms a divisible concatenation. If no such permutation exists, return an empty list.

Β 

Example 1:

Input: nums = [3,12,45], k = 5

Output: [3,12,45]

Explanation:

PermutationConcatenated ValueDivisible by 5
[3, 12, 45]31245Yes
[3, 45, 12]34512No
[12, 3, 45]12345Yes
[12, 45, 3]12453No
[45, 3, 12]45312No
[45, 12, 3]45123No

The lexicographically smallest permutation that forms a divisible concatenation is [3,12,45].

Example 2:

Input: nums = [10,5], k = 10

Output: [5,10]

Explanation:

PermutationConcatenated ValueDivisible by 10
[5, 10]510Yes
[10, 5]105No

The lexicographically smallest permutation that forms a divisible concatenation is [5,10].

Example 3:

Input: nums = [1,2,3], k = 5

Output: []

Explanation:

Since no permutation of nums forms a valid divisible concatenation, return an empty list.

Β 

Constraints:

  • 1 <= nums.length <= 13
  • 1 <= nums[i] <= 105
  • 1 <= k <= 100

Solution


Python3

class Solution:
    def concatenatedDivisibility(self, nums: List[int], k: int) -> List[int]:
        N = len(nums)
        P = [pow(10, len(str(x)), k) for x in nums]
        idx = sorted(range(N), key = lambda i : nums[i])
        full_mask = (1 << N) - 1
 
        @cache
        def dp(mask, rem):
            if mask == full_mask:
                return [] if rem == 0 else None
            
            for j in idx:
                if mask & (1 << j): continue
 
                newMask = mask | (1 << j)
                newRem = (rem * P[j] + nums[j]) % k
                suffix = dp(newMask, newRem)
 
                if suffix is not None:
                    return [nums[j]] + suffix
            
            return None
        
        ans = dp(0, 0)
        return ans if ans is not None else []