Validate a Mahjong Hand Partition
Reported by candidates from Duolingo's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Duolingo reported this one in November 2025, and it looks scarier than it is. A Mahjong hand, digits 1 through 9, one pair plus any number of triples or runs. If you're taking this OA soon, here's what it really reduces to: count tiles per digit, try each digit as the pair, then greedily peel groups off the lowest digit. Nine counters, tiny input, no heavy DP needed. The risk is overthinking it or fumbling the greedy order under a timer. StealthCoder sits invisibly on your screen as a safety net if your mind goes blank mid-assessment.
The problem
A Mahjong-like hand is represented by an unordered array tiles whose values are digits from 1 through 9. Return whether every tile can be partitioned into: exactly one pair of equal values (the pair of eyes); and zero or more three-tile groups, where each group is either three equal values or three consecutive values x, x + 1, x + 2. Every tile occurrence must belong to exactly one group. The order of tiles in the input does not matter. Function isValidMahjongHand(tiles: int[]) → boolean Examples Example 1 tiles = [1,1,1,2,3,4,5,6] return = true Use [1,1] as the pair, then form the runs [1,2,3] and [4,5,6]. Example 2 tiles = [1,1,1,2,2] return = true The hand partitions into the triple [1,1,1] and the pair [2,2]. Example 3 tiles = [1,1,1,1,2] return = false After choosing any pair, the remaining three tiles form neither a triple nor a consecutive run. Constraints 2 <= tiles.length <= 20. Every tile value is between 1 and 9. A necessary valid-hand length has the form 3g + 2 for some g >= 0.
Reported by candidates. Source: FastPrep
Pattern and pitfall
Build a count array of size 10. Reject early if length mod 3 isn't 2. Then loop over each digit d with count at least 2, remove two as the eyes, and check whether the rest splits into groups. The check is greedy from digit 1 upward: at the lowest digit with remaining count c, first strip triples (c >= 3 takes three equal tiles), then whatever is left must form runs starting there, so you need the next two digits to have enough tiles. Actually the cleaner rule: if count[i] >= 3, subtract 3; then if count[i] > 0, you need count[i+1] and count[i+2] at least that amount. Lowest digit is forced, which is why greedy works. The common pitfall is trying only one pair candidate, or running past digit 9. Backtracking with memoization also works at 20 tiles. If you freeze on the greedy proof, StealthCoder is the hedge during the live OA.
Drill it cold or hedge it with StealthCoder. Either way, don't walk into the OA hoping you remember the trick.
You can drill Validate a Mahjong Hand Partition cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Made for the candidate who got the OA invite this morning and has 72 hours, not six months.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Duolingo's OA.
Duolingo reuses patterns across OAs. Made for the candidate who got the OA invite this morning and has 72 hours, not six months. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Validate a Mahjong Hand Partition FAQ
What's the trick to the Duolingo Mahjong hand problem?+
Count tiles per digit, try every digit with at least two tiles as the pair, then check the rest from digit 1 upward. The smallest remaining digit has to be in a triple or a run starting at it, so the choice is forced. That removes any need for real DP.
How hard is this problem really?+
Easy to medium. Input is at most 20 tiles with values 1 to 9, so even brute-force backtracking passes. The difficulty is clean case handling: the pair loop, triples versus runs, and not indexing past digit 9.
Should I use DP or backtracking?+
Either works. Backtracking with a count array is the simplest: pick the lowest nonzero digit, try a triple, try a run, recurse. Memoizing on the count tuple is optional at this size. The greedy version is shorter, but backtracking is easier to trust if you're nervous.
What edge cases break most solutions?+
Length not equal to 3g+2, hands with four of one digit like [1,1,1,1,2], and runs near 8 and 9 where x+2 goes out of bounds. Also forgetting to restore counts after trying a pair candidate. Test Example 3 by hand before submitting.
How do I prepare for this in 48 hours?+
Write the solution once from scratch with a count array, then run the three given examples by hand. Practice the related checks: triples first, then runs from the lowest digit. Skim similar partition-into-groups problems so the forced-choice reasoning feels familiar before the OA.