Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using core interview patterns strategy.
You are given an integer n.
A number is called digitorial if the sum of the factorials of its digits is equal to the number itself.
Determine whether any permutation of n (including the original order) forms a digitorial number.
Return true if such a permutation exists, otherwise return false.
Note:
x, denoted as x!, is the product of all positive integers less than or equal to x, and 0! = 1.Example 1:
Input: n = 145
Output: true
Explanation:
The number 145 itself is digitorial since 1! + 4! + 5! = 1 + 24 + 120 = 145. Thus, the answer is true.
Example 2:
Input: n = 10
Output: false
Explanation:
10 is not digitorial since 1! + 0! = 2 is not equal to 10, and the permutation "01" is invalid because it starts with zero.
Constraints:
1 <= n <= 109Problem summary: You are given an integer n. A number is called digitorial if the sum of the factorials of its digits is equal to the number itself. Determine whether any permutation of n (including the original order) forms a digitorial number. Return true if such a permutation exists, otherwise return false. Note: The factorial of a non-negative integer x, denoted as x!, is the product of all positive integers less than or equal to x, and 0! = 1. A permutation is a rearrangement of all the digits of a number that does not start with zero. Any arrangement starting with zero is invalid.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: General problem-solving
145
10
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3848: Check Digitorial Permutation
class Solution {
private static final int[] f = new int[10];
static {
f[0] = 1;
for (int i = 1; i < 10; i++) {
f[i] = f[i - 1] * i;
}
}
public boolean isDigitorialPermutation(int n) {
int x = 0;
int y = n;
while (y > 0) {
x += f[y % 10];
y /= 10;
}
char[] a = String.valueOf(x).toCharArray();
char[] b = String.valueOf(n).toCharArray();
Arrays.sort(a);
Arrays.sort(b);
return Arrays.equals(a, b);
}
}
// Accepted solution for LeetCode #3848: Check Digitorial Permutation
func isDigitorialPermutation(n int) bool {
f := make([]int, 10)
f[0] = 1
for i := 1; i < 10; i++ {
f[i] = f[i-1] * i
}
x := 0
y := n
for y > 0 {
x += f[y%10]
y /= 10
}
a := []byte(strconv.Itoa(x))
b := []byte(strconv.Itoa(n))
sort.Slice(a, func(i, j int) bool { return a[i] < a[j] })
sort.Slice(b, func(i, j int) bool { return b[i] < b[j] })
return string(a) == string(b)
}
# Accepted solution for LeetCode #3848: Check Digitorial Permutation
@cache
def f(x: int) -> int:
if x < 2:
return 1
return x * f(x - 1)
class Solution:
def isDigitorialPermutation(self, n: int) -> bool:
x, y = 0, n
while y:
x += f(y % 10)
y //= 10
return sorted(str(x)) == sorted(str(n))
// Accepted solution for LeetCode #3848: Check Digitorial Permutation
// Rust example auto-generated from java reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (java):
// // Accepted solution for LeetCode #3848: Check Digitorial Permutation
// class Solution {
// private static final int[] f = new int[10];
//
// static {
// f[0] = 1;
// for (int i = 1; i < 10; i++) {
// f[i] = f[i - 1] * i;
// }
// }
//
// public boolean isDigitorialPermutation(int n) {
// int x = 0;
// int y = n;
//
// while (y > 0) {
// x += f[y % 10];
// y /= 10;
// }
//
// char[] a = String.valueOf(x).toCharArray();
// char[] b = String.valueOf(n).toCharArray();
//
// Arrays.sort(a);
// Arrays.sort(b);
//
// return Arrays.equals(a, b);
// }
// }
// Accepted solution for LeetCode #3848: Check Digitorial Permutation
function isDigitorialPermutation(n: number): boolean {
const f: number[] = new Array(10);
f[0] = 1;
for (let i = 1; i < 10; i++) {
f[i] = f[i - 1] * i;
}
let x = 0;
let y = n;
while (y > 0) {
x += f[y % 10];
y = Math.floor(y / 10);
}
const a = x.toString().split('').sort().join('');
const b = n.toString().split('').sort().join('');
return a === b;
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.