LeetCode 3483: Unique 3-Digit Even Numbers – Java Backtracking Solution

Generate all possible three-digit numbers with backtracking, handle duplicate digits correctly, and count only distinct even numbers.

Krishna Shrivastava
5 views
LinkedInGithubX
0
0
LeetCode 3483: Unique 3-Digit Even Numbers – Java Backtracking Solution
Listen to articleAudio version
Ad

Introduction

What happens when a small collection of digits needs to be arranged into valid three-digit numbers?

There are several conditions to satisfy at the same time:

  1. The number must contain exactly three digits.
  2. The first digit cannot be 0.
  3. The number must be even.
  4. A digit can only be used as many times as it appears in the input.
  5. Duplicate numbers should be counted only once.

Because the input contains at most 10 digits, backtracking is a natural approach. Every possible arrangement can be generated, checked, and stored in a HashSet to ensure that only distinct numbers are counted.

Question Link

LeetCode 3483 – Unique 3-Digit Even Numbers

Approach

The idea is to build the number one digit at a time.

A recursive function maintains:

  1. curr — the number currently being constructed.
  2. boo[] — tracks which positions of the input array have already been used.
  3. ms — a HashSet containing all valid three-digit numbers.

At every recursion level, each unused digit is selected and appended to curr.

Once three digits have been selected, three checks are performed:

Leading zero

012

is not a valid three-digit number, so it is rejected.

Even number

The generated number must be divisible by 2.

Distinctness

The generated number is inserted into a HashSet, which automatically removes duplicates.

Why Track Indices Instead of Digits?

Consider:

digits = [0, 2, 2]

The digit 2 appears twice.

Therefore, a valid number such as:

220

must be allowed.

The boolean array tracks positions, not just digit values:

Index: 0 1 2
Digit: 0 2 2

The two copies of 2 are therefore treated as two separate usable elements.

The HashSet handles the other side of the problem: different index selections can produce the same number, but the final answer should count that number only once.

Java Implementation

class Solution {

// Stores every distinct valid three-digit number.
HashSet<String> ms = new HashSet<>();

public void sol(int[] dig, String curr, boolean[] boo) {

// Once three digits are selected,
// check whether the generated number is valid.
if (curr.length() == 3) {

// A three-digit number cannot start with zero.
if (curr.charAt(0) == '0') {
return;
}

// Check whether the number is even.
// HashSet automatically handles duplicates.
if (ch(curr) && !ms.contains(curr)) {
ms.add(curr);
}

return;
}

// Try every digit that has not been used yet.
for (int i = 0; i < dig.length; i++) {

// Skip the current digit if its array position
// has already been used in this number.
if (boo[i]) continue;

String vl = String.valueOf(dig[i]);

// Mark this position as used.
boo[i] = true;

// Add the digit to the current number
// and continue building the number.
sol(dig, curr + vl, boo);

// Backtrack: make this position available
// for another possible arrangement.
boo[i] = false;
}
}

// Checks whether the generated number is even.
public boolean ch(String s) {
int n = Integer.valueOf(s);
return n % 2 == 0 ? true : false;
}

public int totalNumbers(int[] digits) {

// Tracks which positions of the input array
// are currently being used.
boolean[] boo = new boolean[digits.length];

// Start generating numbers from an empty string.
sol(digits, "", boo);

// HashSet contains only distinct valid numbers.
return ms.size();
}
}

Backtracking in Action

Consider:

digits = [1, 2, 3, 4]

The recursion starts with an empty string:

""

Choose 1:

"1"

Then choose 2:

"12"

Then choose 3:

"123"

The number has three digits, but 123 is odd, so it is rejected.

Backtracking returns to:

"12"

and tries 4:

"124"

This number is three digits, does not start with zero, and is even.

Therefore:

124 → valid

The recursion continues exploring other arrangements.

Handling Duplicate Digits

Consider:

digits = [0, 2, 2]

The two 2s have different indices.

Some recursion branches may therefore generate the same number:

202

from different copies of 2.

Without a HashSet, these would be counted multiple times.

With:

HashSet<String> ms

only one copy remains.

The valid numbers are:

202
220

Therefore:

Answer = 2

Dry Run

Consider:

digits = [1, 2, 3, 4]

Some of the generated permutations include:

123 → odd → reject
124 → even → add
132 → even → add
134 → even → add
142 → even → add

The recursion continues for all possible selections.

Eventually, the set contains:

124
132
134
142
214
234
312
314
324
342
412
432

So:

ms.size() = 12

The final answer is:

12

Why a HashSet Is Useful

There are two separate concerns in this problem.

Generating valid arrangements

Backtracking ensures that every possible selection of three positions is explored.

Removing duplicates

The HashSet ensures that identical numbers generated through different index choices are counted only once.

This combination is especially useful when the input contains duplicate values.

Complexity Analysis

Let n be the number of digits.

At most 10 digits are given, and only three positions are selected.

The number of possible index arrangements is:

P(n, 3) = n × (n - 1) × (n - 2)

Therefore, the number of generated arrangements is O(n³).

For each completed arrangement, converting/checking the three-digit number takes constant time because the number always has exactly three digits.

Time Complexity

O(n³)

With n ≤ 10, this is very small in practice.

Space Complexity

The recursion depth is at most 3, while the HashSet stores the distinct valid numbers.

So the auxiliary recursion space is O(1), excluding the result set.

The result set contains at most a constant number of three-digit numbers because there are only 900 possible three-digit numbers.

A Simpler Observation

There is another way to think about the problem.

A three-digit even number has the structure:

Hundreds → Tens → Units

The units digit must be one of:

0, 2, 4, 6, 8

The hundreds digit cannot be zero.

The tens digit can be any remaining available digit.

This means the problem could also be solved by directly choosing:

first digit
second digit
third digit

and checking whether the resulting number is valid.

The backtracking solution generalizes this idea nicely because it systematically explores all possibilities.

Interview Tip

When a problem asks to create numbers, strings, or arrangements from a small collection of elements, look for permutation/backtracking patterns.

A useful checklist is:

What is being built?
How many elements are needed?
Can an element be reused?
How are duplicates handled?
What makes a completed arrangement valid?

For this problem:

Build → 3-digit number
Reuse → No, each copy once
Duplicates → HashSet
Validity → No leading zero + even

That immediately points toward a small backtracking solution.

Conclusion

LeetCode 3483 is a good introduction to combining backtracking with duplicate handling.

The recursive function explores every possible three-digit arrangement while the boolean array ensures that each input position is used at most once. Once a number is completed, it is checked for the leading-zero and even-number conditions.

Finally, a HashSet guarantees that duplicate numbers are counted only once.

With at most 10 input digits and only three positions to fill, the brute-force search remains highly efficient and easy to understand.

Ai Assistant Kas