Smallest Divisible Digit Product II
HardUpdated: Aug 2, 2025
Practice on:
Problem
You are given a string num which represents a positive integer, and an integer t.
A number is called zero-free if none of its digits are 0.
Return a string representing the smallest zero-free number greater than or equal to num such that the product of its digits is divisible by
t. If no such number exists, return "-1".
Examples
Example 1
Input: num = "1234", t = 256
Output: "1488"
Explanation:
The smallest zero-free number that is greater than 1234 and has the product of
its digits divisible by 256 is 1488, with the product of its digits equal to
256.
Example 2
Input: num = "12355", t = 50
Output: "12355"
Explanation:
12355 is already zero-free and has the product of its digits divisible by 50,
with the product of its digits equal to 150.
Example 3
Input: num = "11111", t = 26
Output: "-1"
Explanation:
No number greater than 11111 has the product of its digits divisible by 26.
Constraints
2 <= num.length <= 2 * 10^5numconsists only of digits in the range['0', '9'].numdoes not contain leading zeros.1 <= t <= 1014
Solution
Method 1 – Greedy Digit DP (with Backtracking for Small t)
Intuition
We need the smallest zero-free number >= num whose digit product is divisible by t. For small t, we can use digit DP with memoization. For large t, the problem is very hard in general, but for practical constraints, we can use greedy and pruning.
Approach
- Use digit DP: for each position, try all digits 1-9 (no zeros), and keep track of the product modulo t.
- If the current prefix is already greater than num, we can use the smallest digits.
- If not, we must match or exceed the current digit in num.
- If t is large, limit the search (e.g., only try to change the first few digits, then fill with 1's).
- If no answer is found, return -1.
Code
Python
class Solution:
def smallestNumber(self, num: str, t: int) -> str:
from functools import lru_cache
n = len(num)
digits = [int(c) for c in num]
@lru_cache(maxsize=None)
def dp(i, tight, prod):
if i == n:
return '' if prod % t == 0 else None
start = digits[i] if tight else 1
for d in range(start, 10):
if d == 0: continue
res = dp(i+1, tight and d == digits[i], (prod * d) % t)
if res is not None:
return str(d) + res
return None
ans = dp(0, True, 1)
if ans is not None:
return ans
# Try to increase the number by changing the first non-9 digit
for i in range(n-1, -1, -1):
if num[i] != '9' and num[i] != '0':
prefix = num[:i] + str(int(num[i])+1)
suffix = '1' * (n-i-1)
candidate = prefix + suffix
prod = 1
for c in candidate:
prod *= int(c)
if prod % t == 0:
return candidate
return "-1"
Java
// Java solution is not practical for large t, but for small t, use digit DP with memoization.
import java.util.*;
class Solution {
public String smallestNumber(String num, int t) {
int n = num.length();
int[] digits = new int[n];
for (int i = 0; i < n; ++i) digits[i] = num.charAt(i) - '0';
Map<String, String> memo = new HashMap<>();
String res = dp(0, true, 1, digits, t, memo);
if (res != null) return res;
// Greedy fallback: try to increment the first non-9 digit
for (int i = n-1; i >= 0; --i) {
if (digits[i] != 9 && digits[i] != 0) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < i; ++j) sb.append(digits[j]);
sb.append(digits[i]+1);
for (int j = i+1; j < n; ++j) sb.append('1');
String candidate = sb.toString();
long prod = 1;
for (char c : candidate.toCharArray()) prod *= c - '0';
if (prod % t == 0) return candidate;
}
}
return "-1";
}
private String dp(int i, boolean tight, int prod, int[] digits, int t, Map<String, String> memo) {
if (i == digits.length) return prod % t == 0 ? "" : null;
String key = i+","+tight+","+prod;
if (memo.containsKey(key)) return memo.get(key);
int start = tight ? digits[i] : 1;
for (int d = start; d <= 9; ++d) {
if (d == 0) continue;
String res = dp(i+1, tight && d == digits[i], (prod * d) % t, digits, t, memo);
if (res != null) {
memo.put(key, d + res);
return d + res;
}
}
memo.put(key, null);
return null;
}
}
Complexity
- ⏰ Time complexity:
O(n * t)for small t (digit DP), but can be exponential for large t. - 🧺 Space complexity:
O(n * t)for memoization.