2729. Check if The Number is Fascinating
Problem Description
You are given a 3-digit integer n
(a number between 100 and 999).
A number is called fascinating if it meets a specific condition after performing the following steps:
- Calculate
2 * n
and3 * n
- Concatenate the three numbers together:
n
,2 * n
, and3 * n
(join them as a string, one after another) - Check if the resulting concatenated number contains each digit from 1 to 9 exactly once, with no 0's present
Your task is to determine whether the given number n
is fascinating or not. Return true
if it is fascinating, false
otherwise.
Example walkthrough:
- If
n = 192
- Then
2 * n = 384
and3 * n = 576
- Concatenating gives us:
192384576
- This contains the digits 1, 2, 3, 4, 5, 6, 7, 8, 9 exactly once each
- No zeros are present
- Therefore, 192 is a fascinating number
Solution Explanation:
The solution concatenates n
, 2*n
, and 3*n
into a single string s
. It then sorts all the characters in this string and checks if the sorted result equals "123456789"
. If the sorted string matches exactly, it means we have each digit from 1-9 appearing exactly once, making the number fascinating.
Intuition
The key insight is recognizing that we need to verify two conditions: the concatenated string must contain exactly the digits 1-9, with each appearing once, and no zeros.
When we concatenate n
, 2*n
, and 3*n
, we get a string of digits. To check if this string contains each digit from 1 to 9 exactly once, we could:
- Count the frequency of each digit and verify each appears exactly once
- Check the length is exactly 9 and verify no duplicates exist
- Sort the string and compare it to a known pattern
The third approach is the most elegant. If we sort all the characters in our concatenated string, and it contains exactly one of each digit from 1-9, then the sorted result must be "123456789"
. This single comparison handles all our requirements:
- If there's a 0, the sorted string would start with "0"
- If any digit is missing, the string would be too short
- If any digit appears more than once, the string would be too long or have duplicates
- If the string has exactly the digits 1-9 once each, sorting will produce exactly
"123456789"
This transforms our complex validation problem into a simple string comparison after sorting, making the solution both concise and efficient.
Learn more about Math patterns.
Solution Approach
The implementation follows a straightforward approach:
-
String Concatenation: First, we convert
n
and its multiples to strings and concatenate them:s = str(n) + str(2 * n) + str(3 * n)
This creates a single string containing all digits from
n
,2*n
, and3*n
in sequence. -
Sorting the String: We sort all characters in the concatenated string:
sorted(s)
This returns a list of characters in ascending order. For example, if
s = "192384576"
, sorting gives us['1', '2', '3', '4', '5', '6', '7', '8', '9']
. -
Join and Compare: We join the sorted characters back into a string and compare with the target pattern:
"".join(sorted(s)) == "123456789"
The
join()
method converts the sorted list back to a string. If this equals"123456789"
, we know that:- The string has exactly 9 characters
- Each digit from 1-9 appears exactly once
- No zeros are present (otherwise the sorted string would start with "0")
The entire check is done in a single line, making the solution both elegant and efficient. The time complexity is O(1)
since we're always dealing with a fixed-size string (9 characters), and the space complexity is also O(1)
for the same reason.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with n = 192
:
Step 1: Calculate multiples
n = 192
2 * n = 384
3 * n = 576
Step 2: Concatenate the numbers
- Convert each to string:
"192"
,"384"
,"576"
- Concatenate them:
s = "192384576"
Step 3: Sort the concatenated string
- Break
s
into individual characters:['1', '9', '2', '3', '8', '4', '5', '7', '6']
- Sort them:
['1', '2', '3', '4', '5', '6', '7', '8', '9']
Step 4: Join and compare
- Join the sorted characters:
"123456789"
- Compare with target:
"123456789" == "123456789"
→True
Since the sorted string exactly matches "123456789"
, we confirm that 192
is a fascinating number.
Counter-example with n = 123
:
2 * n = 246
,3 * n = 369
- Concatenated:
s = "123246369"
- Sorted:
"122334669"
- Compare:
"122334669" != "123456789"
→False
The sorted string doesn't match because we have duplicate digits (2, 3, 6 appear twice) and missing digits (5, 7, 8), so 123
is not fascinating.
Solution Implementation
1class Solution:
2 def isFascinating(self, n: int) -> bool:
3 """
4 Check if a number n is fascinating.
5 A number is fascinating if concatenating n, 2*n, and 3*n
6 results in a pandigital number containing all digits 1-9 exactly once.
7
8 Args:
9 n: An integer to check
10
11 Returns:
12 True if n is fascinating, False otherwise
13 """
14 # Concatenate n, 2*n, and 3*n as strings
15 concatenated_string = str(n) + str(2 * n) + str(3 * n)
16
17 # Sort the concatenated string and check if it equals "123456789"
18 # This ensures all digits 1-9 appear exactly once
19 return "".join(sorted(concatenated_string)) == "123456789"
20
1class Solution {
2 public boolean isFascinating(int n) {
3 // Concatenate n, 2*n, and 3*n into a single string
4 String concatenatedString = "" + n + (2 * n) + (3 * n);
5
6 // Array to count occurrences of each digit (0-9)
7 int[] digitCount = new int[10];
8
9 // Iterate through each character in the concatenated string
10 for (char character : concatenatedString.toCharArray()) {
11 // Convert character to digit and increment its count
12 // If any digit appears more than once, return false
13 if (++digitCount[character - '0'] > 1) {
14 return false;
15 }
16 }
17
18 // A fascinating number should:
19 // 1. Not contain the digit 0 (digitCount[0] should be 0)
20 // 2. Have exactly 9 digits (each digit 1-9 appearing exactly once)
21 return digitCount[0] == 0 && concatenatedString.length() == 9;
22 }
23}
24
1class Solution {
2public:
3 bool isFascinating(int n) {
4 // Concatenate n, 2*n, and 3*n into a single string
5 string concatenatedString = to_string(n) + to_string(n * 2) + to_string(n * 3);
6
7 // Sort the characters in the string to check if it contains digits 1-9 exactly once
8 sort(concatenatedString.begin(), concatenatedString.end());
9
10 // A fascinating number should contain all digits from 1 to 9 exactly once
11 // After sorting, the string should be "123456789"
12 return concatenatedString == "123456789";
13 }
14};
15
1/**
2 * Checks if a number n is fascinating.
3 * A number is fascinating if concatenating n, 2*n, and 3*n results in a string
4 * containing all digits from 1 to 9 exactly once (no 0s allowed).
5 *
6 * @param n - The number to check
7 * @returns true if the number is fascinating, false otherwise
8 */
9function isFascinating(n: number): boolean {
10 // Concatenate n, 2*n, and 3*n into a single string
11 const concatenatedString: string = `${n}${n * 2}${n * 3}`;
12
13 // Sort the characters in the string and check if it equals "123456789"
14 // This ensures all digits 1-9 appear exactly once
15 return concatenatedString.split('').sort().join('') === '123456789';
16}
17
Time and Space Complexity
Time Complexity: O(1)
The time complexity breaks down as follows:
- Converting
n
,2*n
, and3*n
to strings:O(log n)
for each conversion, but sincen
is bounded (must be a 3-digit number to create a 9-digit concatenation), this is effectivelyO(1)
- String concatenation:
O(1)
since we're concatenating exactly 3 strings of fixed length (3 digits each) - Sorting the 9-character string:
O(k log k)
wherek = 9
, which isO(1)
- String comparison:
O(1)
for comparing two 9-character strings
Since all operations work on fixed-size data (9 characters), the overall time complexity is O(1)
.
Space Complexity: O(1)
The space complexity analysis:
- String
s
stores exactly 9 characters:O(1)
- The sorted string creates a new string of 9 characters:
O(1)
- Temporary variables for multiplication and string conversion:
O(1)
All space usage is constant regardless of the input value (as long as it's a valid 3-digit number), resulting in O(1)
space complexity.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Not Handling Edge Cases with Leading Zeros
While the current solution works correctly, a common mistake when solving this problem is trying to optimize by checking the length first or using set operations without considering all requirements:
Incorrect Approach:
def isFascinating(self, n: int) -> bool:
s = str(n) + str(2 * n) + str(3 * n)
return len(s) == 9 and set(s) == set("123456789")
Why it fails: This approach using sets would incorrectly accept numbers that have duplicate digits as long as all digits 1-9 are present. For example, if the concatenation was "112345679", the set would still contain all required digits, but it's not a valid fascinating number.
2. Integer Overflow Concerns in Other Languages
If implementing this in languages with fixed integer sizes, concatenating as integers rather than strings could cause overflow:
Problematic Approach (in concept):
def isFascinating(self, n: int) -> bool:
# Trying to concatenate as numbers instead of strings
concatenated = n * 1000000 + (2 * n) * 1000 + (3 * n)
# Then check digits...
Solution: Always use string concatenation for this problem to avoid numerical overflow and maintain simplicity.
3. Forgetting About the Zero Constraint
A subtle pitfall is not explicitly checking for zeros. While the sorted string comparison inherently handles this, some alternative approaches might miss it:
Incorrect Approach:
def isFascinating(self, n: int) -> bool:
s = str(n) + str(2 * n) + str(3 * n)
if len(s) != 9:
return False
digit_count = [0] * 10
for digit in s:
digit_count[int(digit)] += 1
# Forgot to check if digit_count[0] == 0!
return all(digit_count[i] == 1 for i in range(1, 10))
Correct Fix: Add explicit zero check:
return digit_count[0] == 0 and all(digit_count[i] == 1 for i in range(1, 10))
The beauty of the sorted string approach is that it implicitly handles all these edge cases - if there's a zero, the sorted string would be "012345678" or similar, which won't match "123456789".
What's the output of running the following function using input [30, 20, 10, 100, 33, 12]
?
1def fun(arr: List[int]) -> List[int]:
2 import heapq
3 heapq.heapify(arr)
4 res = []
5 for i in range(3):
6 res.append(heapq.heappop(arr))
7 return res
8
1public static int[] fun(int[] arr) {
2 int[] res = new int[3];
3 PriorityQueue<Integer> heap = new PriorityQueue<>();
4 for (int i = 0; i < arr.length; i++) {
5 heap.add(arr[i]);
6 }
7 for (int i = 0; i < 3; i++) {
8 res[i] = heap.poll();
9 }
10 return res;
11}
12
1class HeapItem {
2 constructor(item, priority = item) {
3 this.item = item;
4 this.priority = priority;
5 }
6}
7
8class MinHeap {
9 constructor() {
10 this.heap = [];
11 }
12
13 push(node) {
14 // insert the new node at the end of the heap array
15 this.heap.push(node);
16 // find the correct position for the new node
17 this.bubble_up();
18 }
19
20 bubble_up() {
21 let index = this.heap.length - 1;
22
23 while (index > 0) {
24 const element = this.heap[index];
25 const parentIndex = Math.floor((index - 1) / 2);
26 const parent = this.heap[parentIndex];
27
28 if (parent.priority <= element.priority) break;
29 // if the parent is bigger than the child then swap the parent and child
30 this.heap[index] = parent;
31 this.heap[parentIndex] = element;
32 index = parentIndex;
33 }
34 }
35
36 pop() {
37 const min = this.heap[0];
38 this.heap[0] = this.heap[this.size() - 1];
39 this.heap.pop();
40 this.bubble_down();
41 return min;
42 }
43
44 bubble_down() {
45 let index = 0;
46 let min = index;
47 const n = this.heap.length;
48
49 while (index < n) {
50 const left = 2 * index + 1;
51 const right = left + 1;
52
53 if (left < n && this.heap[left].priority < this.heap[min].priority) {
54 min = left;
55 }
56 if (right < n && this.heap[right].priority < this.heap[min].priority) {
57 min = right;
58 }
59 if (min === index) break;
60 [this.heap[min], this.heap[index]] = [this.heap[index], this.heap[min]];
61 index = min;
62 }
63 }
64
65 peek() {
66 return this.heap[0];
67 }
68
69 size() {
70 return this.heap.length;
71 }
72}
73
74function fun(arr) {
75 const heap = new MinHeap();
76 for (const x of arr) {
77 heap.push(new HeapItem(x));
78 }
79 const res = [];
80 for (let i = 0; i < 3; i++) {
81 res.push(heap.pop().item);
82 }
83 return res;
84}
85
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
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
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!