Find The K-th Lucky Number
Lucky numbers (digits in {6,8}) enumerated in order are binary numerals over the digit pair — convert k+1 to binary, map bits.
Problem#
A lucky number contains only the digits 6 and 8. Enumerated in ascending order (6, 8, 66, 68, 86, 88, 666, …), return the k-th one (1-indexed) as a string.
Examples#
k=1→"6".k=2→"8";k=4→"68".
Constraints#
1 <= k <= 10^9.
Approach#
There are 2^L lucky numbers of exactly L digits. Decode k by stripping leading-2^L blocks until it fits in the L-digit range, then write the remaining offset in binary mapping bit 0 → 6, 1 → 8.
The cleanest formulation: the n-th lucky number’s digits are the bits of n+1 (binary), excluding the leading 1, with 0 → 6, 1 → 8. So compute binary(k + 1), drop the high bit, map.
Solution#
class Solution {public: string kthLuckyNumber(long long k) { k += 1; string bits; while (k) { bits.push_back('0' + (k & 1)); k >>= 1; } bits.pop_back(); // drop leading 1 reverse(bits.begin(), bits.end()); for (char& c : bits) c = (c == '0') ? '6' : '8'; return bits; }};func kthLuckyNumber(k int64) string { k += 1 bits := []byte{} for k > 0 { bits = append(bits, byte('0'+(k&1))) k >>= 1 } bits = bits[:len(bits)-1] // drop leading 1 // reverse for i, j := 0, len(bits)-1; i < j; i, j = i+1, j-1 { bits[i], bits[j] = bits[j], bits[i] } for i, c := range bits { if c == '0' { bits[i] = '6' } else { bits[i] = '8' } } return string(bits)}class Solution: def kthLuckyNumber(self, k: int) -> str: k += 1 bits = bin(k)[3:] # drop '0b' and the leading 1 return ''.join('6' if c == '0' else '8' for c in bits)var kthLuckyNumber = function(k) { k += 1; let bits = k.toString(2).slice(1); // drop leading 1 let out = ''; for (const c of bits) out += (c === '0') ? '6' : '8'; return out;};class Solution { public String kthLuckyNumber(long k) { k += 1; String bits = Long.toBinaryString(k).substring(1); // drop leading 1 StringBuilder out = new StringBuilder(); for (int i = 0; i < bits.length(); i++) { out.append(bits.charAt(i) == '0' ? '6' : '8'); } return out.toString(); }}function kthLuckyNumber(k: number): string { k += 1; const bits = k.toString(2).slice(1); // drop leading 1 let out = ''; for (const c of bits) out += (c === '0') ? '6' : '8'; return out;}Editorial#
Lucky numbers form a complete binary tree where level L has 2^L nodes — exactly the numbers with L digits. BFS ordering then matches binary representation. Adding 1 places the index inside that ordering; dropping the leading bit gives the within-level offset.
Complexity#
- Time:
O(log k). - Space:
O(log k)for the result string.
Concept revision#
Related#