Overflow in intermediate arithmetic
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.
Build confidence with an intuition-first walkthrough focused on math fundamentals.
A self-dividing number is a number that is divisible by every digit it contains.
128 is a self-dividing number because 128 % 1 == 0, 128 % 2 == 0, and 128 % 8 == 0.A self-dividing number is not allowed to contain the digit zero.
Given two integers left and right, return a list of all the self-dividing numbers in the range [left, right] (both inclusive).
Example 1:
Input: left = 1, right = 22 Output: [1,2,3,4,5,6,7,8,9,11,12,15,22]
Example 2:
Input: left = 47, right = 85 Output: [48,55,66,77]
Constraints:
1 <= left <= right <= 104Problem summary: A self-dividing number is a number that is divisible by every digit it contains. For example, 128 is a self-dividing number because 128 % 1 == 0, 128 % 2 == 0, and 128 % 8 == 0. A self-dividing number is not allowed to contain the digit zero. Given two integers left and right, return a list of all the self-dividing numbers in the range [left, right] (both inclusive).
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Math
1 22
47 85
perfect-number)check-if-number-has-equal-digit-count-and-digit-value)count-the-digits-that-divide-a-number)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #728: Self Dividing Numbers
class Solution {
public List<Integer> selfDividingNumbers(int left, int right) {
List<Integer> ans = new ArrayList<>();
for (int x = left; x <= right; ++x) {
if (check(x)) {
ans.add(x);
}
}
return ans;
}
private boolean check(int x) {
for (int y = x; y > 0; y /= 10) {
if (y % 10 == 0 || x % (y % 10) != 0) {
return false;
}
}
return true;
}
}
// Accepted solution for LeetCode #728: Self Dividing Numbers
func selfDividingNumbers(left int, right int) (ans []int) {
check := func(x int) bool {
for y := x; y > 0; y /= 10 {
if y%10 == 0 || x%(y%10) != 0 {
return false
}
}
return true
}
for x := left; x <= right; x++ {
if check(x) {
ans = append(ans, x)
}
}
return
}
# Accepted solution for LeetCode #728: Self Dividing Numbers
class Solution:
def selfDividingNumbers(self, left: int, right: int) -> List[int]:
def check(x: int) -> bool:
y = x
while y:
if y % 10 == 0 or x % (y % 10):
return False
y //= 10
return True
return [x for x in range(left, right + 1) if check(x)]
// Accepted solution for LeetCode #728: Self Dividing Numbers
impl Solution {
pub fn self_dividing_numbers(left: i32, right: i32) -> Vec<i32> {
fn check(x: i32) -> bool {
let mut y = x;
while y > 0 {
if y % 10 == 0 || x % (y % 10) != 0 {
return false;
}
y /= 10;
}
true
}
(left..=right).filter(|&x| check(x)).collect()
}
}
// Accepted solution for LeetCode #728: Self Dividing Numbers
function selfDividingNumbers(left: number, right: number): number[] {
const check = (x: number): boolean => {
for (let y = x; y; y = Math.floor(y / 10)) {
if (y % 10 === 0 || x % (y % 10) !== 0) {
return false;
}
}
return true;
};
return Array.from({ length: right - left + 1 }, (_, i) => i + left).filter(check);
}
Use this to step through a reusable interview workflow for this problem.
Simulate the process step by step — multiply n times, check each number up to n, or iterate through all possibilities. Each step is O(1), but doing it n times gives O(n). No extra space needed since we just track running state.
Math problems often have a closed-form or O(log n) solution hidden behind an O(n) simulation. Modular arithmetic, fast exponentiation (repeated squaring), GCD (Euclidean algorithm), and number theory properties can dramatically reduce complexity.
Review these before coding to avoid predictable interview regressions.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.