Python 2094.py
class Solution:
def findEvenNumbers(self, digits: List[int]) -> List[int]:
reduced = [] # each digit at most three times
freq = defaultdict(int)
for d in digits:
freq[d] += 1
if freq[d] <= 3:
reduced.append(d)
result = set()
for i1, d1 in enumerate(reduced):
# no leading zero
if d1 == 0:
continue
for i2, d2 in enumerate(reduced):
# use distinct elements
if i1 == i2:
continue
for i3, d3 in enumerate(even):
# use distinct elements and ensure it's even
if i1 != i3 and i2 != i3 and (d3 & 1) == 0:
result.add(d1 * 100 + d2 * 10 + d3)
return sorted(result)
Difficulty
and has an acceptance rate of about 79% (200k+ submissions).
Typical patterns to solve this problem:
- Array
- Enumeration
- Hash Table
- Recursion
- Sorting
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The provided implementation defines a method that receives a list of decimal digits and returns all distinct three-digit even numbers that can be formed by using three different positions from the input. The algorithm proceeds in three logical phases: frequency limiting, combinatorial enumeration, and result collection. Each phase is implemented with straightforward Python constructs, and the code deliberately caps the number of occurrences of any digit to three, which directly influences the size of the search space.
Frequency Limiting and Construction of a Reduced List
The first loop iterates over the original digits array, counts occurrences with a defaultdict, and appends a digit to the auxiliary list reduced only while its count does not exceed three. This step guarantees that no digit will be considered more than three times in subsequent nested loops, effectively bounding the combinatorial explosion when the input contains many repeated values.
reduced = [] # each digit at most three times
freq = defaultdict(int)
for d in digits:
freq[d] += 1
if freq[d] <= 3:
reduced.append(d)
By truncating the multiplicity, the algorithm ensures that the later triple-nested loops operate over a manageable collection even when the original list is large.
Initialization of the Result Container
A set named result is created before the enumeration begins. Using a set automatically discards duplicate numbers that could arise from different index selections producing the same numeric value.
result = set()
Triple-Nested Enumeration with Distinct Index Checks
The core of the method consists of three nested for loops, each iterating over the reduced list with enumerate to obtain both the index and the digit value. The outermost loop selects the hundreds digit, the middle loop selects the tens digit, and the innermost loop selects the units digit. Several guard conditions are applied:
- The hundreds digit cannot be zero, preventing numbers with a leading zero.
- The indices of the three selected digits must be pairwise distinct, ensuring that the same position in the input list is not reused.
- The units digit must be even, verified by a bitwise AND with
1.
When all conditions are satisfied, the three digits are combined into a three-digit integer and added to the result set.
for i1, d1 in enumerate(reduced):
# no leading zero
if d1 == 0:
continue
for i2, d2 in enumerate(reduced):
# use distinct elements
if i1 == i2:
continue
for i3, d3 in enumerate(even):
# use distinct elements and ensure it's even
if i1 != i3 and i2 != i3 and (d3 & 1) == 0:
result.add(d1 * 100 + d2 * 10 + d3)
Edge Cases Handled by the Implementation
The code explicitly addresses several boundary conditions:
- When the input contains zeros, the check
if d1 == 0: continueprevents the formation of numbers like012, which would not be considered valid three-digit numbers. - If the input list has fewer than three distinct positions, the distinct-index checks cause the loops to skip all combinations, resulting in an empty output list.
- Digits that appear more than three times are effectively ignored beyond the third occurrence, which avoids redundant permutations that would otherwise generate identical numbers.
- The evenness test
(d3 & 1) == 0guarantees that only numbers ending with an even digit are collected, satisfying the problem’s requirement for even numbers.
Performance Optimizations Observed
Two primary optimizations are evident:
- Limiting each digit’s frequency to three reduces the size of the
reducedlist, which directly lowers the number of iterations in the triple-nested loops. This is a practical trade-off because any additional copies of a digit beyond three cannot contribute new distinct three-digit numbers. - Storing intermediate results in a
seteliminates the need for an explicit duplicate-removal pass after enumeration. The final conversion to a sorted list is performed once, providing the required ordered output with minimal overhead.
These choices keep the algorithm efficient for typical input sizes while preserving correctness across the defined edge cases.
ELI5 - Simplified Explanation
Imagine having a big pile of colorful number blocks and wanting to build every possible three-digit special tower using those blocks. A special tower is one that ends with an even number, like two, four, six, eight, or zero.
The first part of the code looks through the pile of blocks. It makes sure there are not too many of any one number so that the work stays organized.
Next, the code goes on a hunt to build towers. It picks the first block for the top of the tower, making sure it is not a zero, because a number cannot start with zero. Then it picks a second block for the middle, and finally a third block for the bottom.
To make sure everything stays correct, the code checks that each block used is a different physical piece from the pile. It also checks that the very last block is an even number. If all those rules are met, the code glues those three blocks together to form a new larger number and adds it to a collection. Once every combination has been checked, the collection of numbers is arranged from smallest to biggest just like organizing toys on a shelf.
Code Quality
Complexity Analysis
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | |||||||||
|---|---|---|---|---|---|---|---|---|---|
| author | solutions | ||||||||
| www | AlgoMonster | C++ | Python | Java | TS | ||||
| WalkCCC | C++ | Python | Java | ||||||
| leetcode.ca | C++ | Python | JS | Java | Go | TS | |||
| Progiez | C++ | Python | Java | ||||||
| github | black-shadows | C++ | |||||||
| charles-wangkai | Java | ||||||||
| everthis | JS | ||||||||
| fartem | Ruby | ||||||||
| fsq | C++ | ||||||||
| JoshCrozier | JS | ||||||||
| lkwq007 | Python | ||||||||
| suxrobGM | C# | ||||||||
| trung-hn | Python | ||||||||
| varunu28 | Java | ||||||||
| AlgoMonster | C++, Python, Java, TypeScript | ||||||||
| WalkCCC | C++, Python, Java | ||||||||
| leetcode.ca | C++, Go, Java, JavaScript, Python, TypeScript | ||||||||
| Progiez | C++, Java, Python | ||||||||
| black-shadows | C++, C++ | ||||||||
| charles-wangkai | Java | ||||||||
| everthis | JavaScript | ||||||||
| fartem | Ruby | ||||||||
| fsq | C++ | ||||||||
| JoshCrozier | JavaScript | ||||||||
| lkwq007 | Python | ||||||||
| suxrobGM | C# | ||||||||
| trung-hn | Python | ||||||||
| varunu28 | Java |
Videos
Similar Problems
- problem 1295: Find Numbers with Even Number of Digits
Solved On The Same Day
- problem 2089: Find Target Indices After Sorting Array
- problem 2096: Step-By-Step Directions From a Binary Tree Node to Another
- problem 2131: Longest Palindrome by Concatenating Two Letter Words
- problem 2155: All Divisions With the Highest Score of a Binary Array
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality