2269. Find the K-Beauty of a Number
Problem Description
You are given two integers: num
and k
. Your task is to find the k-beauty of num
.
The k-beauty is calculated by counting how many substrings of num
(when treated as a string) satisfy both of these conditions:
- The substring has exactly
k
digits in length - When converted to an integer, it divides
num
evenly (i.e.,num % substring == 0
)
For example, if num = 240
and k = 2
:
- The string representation is "240"
- The substrings of length 2 are: "24" and "40"
- Check if each divides 240:
- 24 divides 240 evenly (240 % 24 = 0) ✓
- 40 divides 240 evenly (240 % 40 = 0) ✓
- The k-beauty is 2
Important notes to remember:
- Leading zeros in substrings are allowed (e.g., "04" from "2040" is valid)
- If a substring equals 0, it cannot be a divisor (division by zero is undefined)
- You need to check all possible consecutive substrings of length
k
The solution approach involves converting num
to a string, sliding a window of size k
across it to get all substrings, converting each substring back to an integer, and checking if it's a non-zero divisor of num
. The code iterates through positions i
from 0
to len(s) - k
, extracts substring s[i:i+k]
, converts it to integer t
, and increments the counter if t != 0
and num % t == 0
.
Intuition
The problem asks us to find substrings of a specific length from a number and check if they divide the original number. The natural way to work with substrings is to convert the number to a string first, since extracting consecutive digits is much easier with string operations than with arithmetic operations.
Once we have the string representation, we need to examine every possible substring of length k
. This immediately suggests using a sliding window approach - we can start at position 0 and extract k
characters, then move to position 1 and extract k
characters, and so on. This ensures we don't miss any valid substrings.
For a string of length n
, the last valid starting position for a substring of length k
would be at index n - k
. This is because we need at least k
characters remaining from that position. Therefore, we iterate from index 0
to n - k
(inclusive), which in Python range notation is range(len(s) - k + 1)
.
For each substring we extract, we need to convert it back to an integer to perform the divisibility check. The key insight here is that we must handle two edge cases:
- The substring might be "00" or "000" etc., which converts to integer
0
. We cannot check divisibility by 0. - The substring might have leading zeros like "04", which is perfectly valid and converts to integer
4
.
The condition if t and num % t == 0
elegantly handles both requirements - it first checks if t
is non-zero (since 0
is falsy in Python), and only then checks if it divides num
evenly.
This straightforward enumeration approach works well because we're simply checking all possibilities without any complex optimization needed.
Learn more about Math and Sliding Window patterns.
Solution Approach
The solution uses a simple enumeration strategy to check all possible substrings of length k
.
Step 1: Convert number to string
s = str(num)
We convert the integer num
to a string s
to easily extract substrings. This allows us to work with individual digits and consecutive sequences without complex arithmetic operations.
Step 2: Initialize counter
ans = 0
We maintain a counter ans
to track how many valid divisors we find.
Step 3: Iterate through all possible starting positions
for i in range(len(s) - k + 1):
We loop through each valid starting position for a substring of length k
. The range goes from 0
to len(s) - k
(inclusive). For example, if s = "240"
and k = 2
, we iterate through positions 0
and 1
, giving us substrings starting at these positions.
Step 4: Extract and convert substring
t = int(s[i : i + k])
For each position i
, we extract a substring of length k
using Python's slice notation s[i : i + k]
. This substring is then converted back to an integer t
. The conversion automatically handles leading zeros - for instance, "04"
becomes 4
.
Step 5: Check divisibility
if t and num % t == 0: ans += 1
We perform two checks:
t
evaluates toTrue
ift != 0
(avoiding division by zero)num % t == 0
checks ift
dividesnum
evenly
If both conditions are met, we increment our counter.
Step 6: Return the result
return ans
After checking all substrings, we return the total count of valid divisors.
The time complexity is O(n * k)
where n
is the number of digits in num
, since we iterate through n - k + 1
positions and for each position, we extract and convert a substring of length k
. The space complexity is O(n)
for storing the string representation of num
.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's trace through the solution with num = 430043
and k = 2
.
Step 1: Convert to string
s = "430043"
- Length of string: 6 digits
Step 2: Determine iteration range
- We need substrings of length
k = 2
- Valid starting positions: from index 0 to
len(s) - k = 6 - 2 = 4
- So we'll check positions 0, 1, 2, 3, and 4
Step 3: Extract and check each substring
Position 0: s[0:2] = "43"
- Convert to integer:
t = 43
- Check: Is
43 ≠ 0
? Yes. Does430043 % 43 = 0
? 430043 ÷ 43 = 10001
, so yes!- Counter:
ans = 1
Position 1: s[1:3] = "30"
- Convert to integer:
t = 30
- Check: Is
30 ≠ 0
? Yes. Does430043 % 30 = 0
? 430043 ÷ 30 = 14334.766...
, so no- Counter remains:
ans = 1
Position 2: s[2:4] = "00"
- Convert to integer:
t = 0
- Check: Is
0 ≠ 0
? No (division by zero not allowed) - Counter remains:
ans = 1
Position 3: s[3:5] = "04"
- Convert to integer:
t = 4
(leading zero is handled) - Check: Is
4 ≠ 0
? Yes. Does430043 % 4 = 0
? 430043 ÷ 4 = 107510.75
, so no- Counter remains:
ans = 1
Position 4: s[4:6] = "43"
- Convert to integer:
t = 43
- Check: Is
43 ≠ 0
? Yes. Does430043 % 43 = 0
? 430043 ÷ 43 = 10001
, so yes!- Counter:
ans = 2
Result: The k-beauty of 430043 is 2 (substrings "43" at positions 0 and 4 both divide 430043 evenly).
Solution Implementation
1class Solution:
2 def divisorSubstrings(self, num: int, k: int) -> int:
3 # Initialize counter for valid k-beauty divisors
4 count = 0
5
6 # Convert number to string for substring extraction
7 num_str = str(num)
8
9 # Iterate through all possible k-length substrings
10 # Loop from index 0 to (length - k), inclusive
11 for i in range(len(num_str) - k + 1):
12 # Extract k-length substring and convert to integer
13 substring_value = int(num_str[i:i + k])
14
15 # Check if substring is non-zero and divides num evenly
16 # (Avoid division by zero and check divisibility)
17 if substring_value != 0 and num % substring_value == 0:
18 count += 1
19
20 return count
21
1class Solution {
2 public int divisorSubstrings(int num, int k) {
3 // Initialize counter for valid k-beauty divisors
4 int count = 0;
5
6 // Convert the number to string for easy substring extraction
7 String numStr = String.valueOf(num);
8
9 // Iterate through all possible k-length substrings
10 // Loop runs from index 0 to (length - k) inclusive
11 for (int i = 0; i <= numStr.length() - k; i++) {
12 // Extract k-length substring starting at index i
13 String substring = numStr.substring(i, i + k);
14
15 // Convert substring to integer
16 int divisor = Integer.parseInt(substring);
17
18 // Check if divisor is non-zero and divides num evenly
19 if (divisor != 0 && num % divisor == 0) {
20 count++;
21 }
22 }
23
24 // Return the total count of valid divisor substrings
25 return count;
26 }
27}
28
1class Solution {
2public:
3 int divisorSubstrings(int num, int k) {
4 int count = 0;
5 string numStr = to_string(num);
6
7 // Iterate through all possible k-length substrings
8 for (int i = 0; i <= numStr.size() - k; ++i) {
9 // Extract k-length substring starting at position i
10 int divisor = stoi(numStr.substr(i, k));
11
12 // Check if divisor is non-zero and divides num evenly
13 // If true, increment count
14 if (divisor != 0 && num % divisor == 0) {
15 count++;
16 }
17 }
18
19 return count;
20 }
21};
22
1/**
2 * Counts the number of k-digit substrings that are divisors of the given number
3 * @param num - The original number to check divisibility against
4 * @param k - The length of substrings to extract
5 * @returns The count of k-digit substrings that divide num evenly
6 */
7function divisorSubstrings(num: number, k: number): number {
8 let count: number = 0;
9 const numString: string = num.toString();
10
11 // Iterate through all possible k-length substrings
12 for (let startIndex: number = 0; startIndex <= numString.length - k; startIndex++) {
13 // Extract k-digit substring starting at current position
14 const substring: string = numString.substring(startIndex, startIndex + k);
15 const substringValue: number = parseInt(substring);
16
17 // Check if substring is non-zero and divides the original number
18 if (substringValue !== 0 && num % substringValue === 0) {
19 count++;
20 }
21 }
22
23 return count;
24}
25
Time and Space Complexity
Time Complexity: O(log num × k)
The algorithm converts the number to a string, which has length O(log num)
(the number of digits in base 10). Then it iterates through all possible substrings of length k
, which gives us O(log num - k + 1)
iterations, simplifying to O(log num)
iterations. In each iteration, we extract a substring of length k
using slicing s[i:i+k]
, which takes O(k)
time, and convert it to an integer, which also takes O(k)
time. The modulo operation takes O(1)
time. Therefore, the overall time complexity is O(log num × k)
.
Space Complexity: O(log num + k)
The space complexity consists of:
- The string representation
s
of the number, which requiresO(log num)
space to store all digits - The substring
s[i:i+k]
created during slicing, which requiresO(k)
space - The integer
t
and other variables useO(1)
space
Since these space requirements don't nest but rather add up, the total space complexity is O(log num + k)
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Division by Zero Error
The most critical pitfall is forgetting to check if the substring value equals zero before performing the modulo operation. When a substring like "00" or "000" is converted to an integer, it becomes 0, and num % 0
will raise a ZeroDivisionError
.
Incorrect Code:
for i in range(len(num_str) - k + 1):
substring_value = int(num_str[i:i + k])
if num % substring_value == 0: # ❌ Crashes when substring_value is 0
count += 1
Correct Approach:
for i in range(len(num_str) - k + 1):
substring_value = int(num_str[i:i + k])
if substring_value != 0 and num % substring_value == 0: # ✓ Check for zero first
count += 1
2. Incorrect Range Calculation
Another common mistake is using the wrong range for iteration, which either misses the last valid substring or goes out of bounds.
Incorrect Code:
# Missing the last valid substring
for i in range(len(num_str) - k): # ❌ Should be len(num_str) - k + 1
substring = num_str[i:i + k]
# Going out of bounds
for i in range(len(num_str)): # ❌ Will create incomplete substrings at the end
substring = num_str[i:i + k]
Correct Approach:
for i in range(len(num_str) - k + 1): # ✓ Includes all valid positions
substring = num_str[i:i + k]
3. Type Confusion with Boolean Check
While Python allows if substring_value
as shorthand for if substring_value != 0
, this can be confusing and less readable, especially for those coming from other languages.
Less Clear:
if substring_value and num % substring_value == 0: # Works but may confuse readers count += 1
More Explicit:
if substring_value != 0 and num % substring_value == 0: # ✓ Clear intent count += 1
4. Edge Case: k Equals String Length
When k
equals the length of the number's string representation, there's only one substring to check (the entire number itself). The code handles this correctly, but developers might overthink and add unnecessary special case handling.
Unnecessary Complexity:
if k == len(num_str):
return 1 if num % num == 0 else 0 # ❌ Redundant special case
else:
# regular logic
The standard iteration approach already handles this case correctly when range(len(num_str) - k + 1)
produces range(1)
, giving exactly one iteration.
Which of the following is a good use case for backtracking?
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
https assets algo monster cover_photos stack svg Sliding Window Maximum Monotonic Stack We have an array and a sliding window defined by a start index and an end index The sliding window moves from left of the array to right There are always k elements in the window The window
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Want a Structured Path to Master System Design Too? Don’t Miss This!