Math & Bit Manipulation
Some problems look like they need a search or a DP, but a small observation about numbers turns them into a formula or a loop over 32 bits. This page collects the tricks that come up again and again: binary exponentiation, XOR cancelling, counting bits, sieves, divisors and gcd counting.
1. What is this pattern for?
The recurring tools:
- Binary exponentiation.
xⁿinO(log n)by squaring: Pow(x, n), Super Pow, Count Good Numbers, matrix powers. - XOR tricks.
a ^ a = 0,a ^ 0 = a: pairs cancel. Single Number I/II/III, XOR subsequences. - Per-bit reasoning. Bits are independent under AND/OR/XOR, so solve one bit position at a time (Minimum Flips, Single Number II).
- Primes and divisors. Sieve of Eratosthenes, divisor pairs up to √n, gcd counting by multiples.
- Counting formulas. Stars and bars, binomials, parity arguments: Bulb Switcher, Reach a Number, Count Valid Sequences.
2. How it works (bisected)
- Write the slow version (multiply n times, try every number, check every pair) and its cost.
- Look at the structure of the numbers: their binary digits, their prime factors, their divisors, their parity.
- Find the invariant that the slow version is secretly computing: "pairs cancel under XOR", "divisors pair up", "each bit is independent", "only perfect squares have an odd number of divisors".
- Replace the loop with the invariant: a formula, a loop over 32 bits, or a loop over
log nsquarings. - Mind the edges: negative numbers, 32-bit overflow, modulo 10⁹ + 7, and 0 / 1.
3. Seeing a problem: how to spot Math / Bit Manipulation
Trigger words
- "without using * / %", "without + −", "in O(1) extra space" with numbers that appear twice / three times
- huge exponents or counts: n up to 10⁹ or 10¹⁵, "return modulo 10⁹ + 7"
- "bitwise AND / OR / XOR", "number of 1 bits", "power of two"
- "count primes", "divisors", "gcd of all pairs", "factorial"
- a simulation over a huge range (bulbs, steps on a number line)
Shape of the input
- One or two integers, often enormous.
- An array where every value appears k times except a few.
- Brute-force smell: a loop up to n with n = 10⁹, or all pairs of an array of 10⁵.
4. When to use it, and when not to
| Reach for math / bits when… | Prefer something else when… |
|---|---|
| An exponent or count is huge (10⁹+) and the step is a multiplication | The step isn't a product or linear map: look for DP or a closed form |
| Values appear in pairs/triples and you need O(1) space | You may use O(n) space and clarity matters: a hash map is fine |
| Operations are bitwise and bits don't interact | Carries connect the bits (addition): handle them explicitly |
| You need primes or divisors of many numbers | You need them for one number: trial division up to √n is enough |
Cost: fast power is O(log n), per-bit loops are O(32 · n), the sieve is O(n log log n), and gcd counting over multiples is O(M log M) by the harmonic series.
5. The Python template (memorize this)
# A) binary exponentiation: x**n mod m in O(log n)
def fast_pow(x, n, m):
result = 1
x %= m
while n:
if n & 1: # this bit of n is set
result = result * x % m
x = x * x % m # x, x^2, x^4, x^8, ...
n >>= 1
return result
# B) XOR cancelling: the value that appears an odd number of times
def odd_one_out(nums):
acc = 0
for v in nums:
acc ^= v # a ^ a = 0, so pairs vanish
return acc
# C) sieve of Eratosthenes: is_prime for every number below n
def sieve(n):
is_prime = [True] * n
is_prime[0:2] = [False, False]
p = 2
while p * p < n:
if is_prime[p]:
for multiple in range(p * p, n, p):
is_prime[multiple] = False
p += 1
return is_prime
What the code is doing, line by line:
n & 1reads the lowest bit of the exponent;n >>= 1moves to the next bit. Each set bit multiplies in the matching powerx^(2^k).- Reducing modulo
mafter every multiplication keeps the numbers small (in Python it's about speed; in other languages it prevents overflow). - XOR is commutative and associative, so the order doesn't matter: every value that occurs an even number of times cancels to 0.
- The sieve starts crossing out at
p * p: smaller multiples ofphave a smaller prime factor and were crossed out already.
Dry run of template A for 3¹³ mod 1000 (13 = 1101 in binary):
| bit of n | x (before squaring) | result |
|---|---|---|
| 1 | 3 | 3 |
| 0 | 9 | 3 |
| 1 | 81 | 243 |
| 1 | 561 (= 6561 mod 1000) | 323 (= 243 · 561 mod 1000) |
Four squarings instead of twelve multiplications; 3¹³ = 1,594,323, so the last three digits 323 check out.
6. How to remember it forever
How this hook works: what “Square and skip” means
What the slogan means, phrase by phrase
- “Square”
- In fast exponentiation, square the base every round: x, x², x⁴, x⁸ …
- “and skip”
- Multiply that power into the result only when the matching bit of the exponent is 1. Skip it otherwise.
- “XOR: pairs vanish”
a ^ a = 0anda ^ 0 = a, so XOR-ing everything cancels every pair and leaves the odd one out.- “Bits: one column at a time”
- Each bit position is independent, so you can count or decide per column.
Why this picture fits the pattern: Math and bit problems each hide one structural fact (binary digits, pairs cancelling, divisors coming in pairs) that turns a slow loop into O(log n) or O(1). The slogan bundles the three you'll use most.
The story → the code
| In the story | In the code |
|---|---|
| Square the base | x = x * x % m |
| This bit is set: multiply | if n & 1: result = result * x % m |
| Next bit | n >>= 1 |
| Pairs vanish | acc ^= v |
Watch it on numbers
Compute 3¹³. 13 in binary is 1101 = 8 + 4 + 1.
- Bit 1 is set: result = 3. Square: x = 9.
- Bit 0: skip. Square: x = 81.
- Bit 1: result = 3 × 81 = 243. Square: x = 6561.
- Bit 1: result = 243 × 6561 = 1,594,323. That's 4 rounds instead of 12 multiplications.
- XOR on
[4, 1, 2, 1, 2]: the 1s cancel, the 2s cancel, 4 is left.
The trap it saves you from
Forgetting % m after every multiply (the numbers grow huge and slow), and Python's negative integers behaving as if they had infinite bits. Mask with & 0xFFFFFFFF for 32-bit answers.
It still works when…
Single Number is pairs vanishing. Counting Bits uses bits[i] = bits[i >> 1] + (i & 1). Bulb Switcher: a bulb is toggled once per divisor, divisors come in pairs, so only perfect squares stay on.
Picture
A light switch flipped twice is back where it started: that's XOR, and it's also why only perfect-square bulbs stay on.
Chant
"Bits are independent, divisors come in pairs, squares grow fast."
Safety rule
"Mask, mod, and mind the sign." 32-bit masks in Python, mod after every multiply, and negative numbers.
7. LeetCode problems, solved step by step
Medium 50. Pow(x, n) Start here Google Meta Amazon Cisco Microsoft
Problem: Compute xⁿ for a float x and an integer n (possibly negative).
x = 2.00000, n = 101024.00000x = 2.10000, n = 39.26100Constraints: -100.0 < x < 100.0 · -2³¹ ≤ n ≤ 2³¹-1 · n is an integer. · Either x is not zero or n > 0. · -10⁴ ≤ xn ≤ 10⁴
Hint 1
How can you get x⁸ with only 3 multiplications?
Hint 2
Use the binary representation of n.
From brute force to the pattern: n multiplications vs log n squarings.
Spot it: Binary exponentiation: xⁿ is the product of x^(2^k) over the set bits of n. Square the base each step.
Why not another pattern? Multiplying n times is O(n) with |n| up to 2³¹.
Approach:
- If
n < 0:x = 1/x,n = −n. - While
n: ifn & 1,result *= x;x *= x;n >>= 1.
class Solution:
def myPow(self, x: float, n: int) -> float:
if n < 0:
x, n = 1 / x, -n # x^-n = (1/x)^n
result = 1.0
while n:
if n & 1:
result *= x # this power of two is part of n
x *= x # x, x^2, x^4, x^8, ...
n >>= 1
return result
What the code is doing, line by line:
- After
ksquarings,xholdsx^(2^k). - Each set bit of
nmultiplies in the matching power. - Negative exponents invert the base first.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
n = 0→ 1.- Negative
n. n = −2³¹.
Complexity: O(log n) time, O(1) space.
Medium 260. Single Number III Google Amazon
Problem: Exactly two elements appear once; all others twice. Return the two (any order) in O(n) time, O(1) space.
nums = [1,2,1,3,2,5][3,5]nums = [-1,0][-1,0]Constraints: 2 ≤ nums.length ≤ 3 * 10⁴ · -2³¹ ≤ nums[i] ≤ 2³¹ - 1 · Each integer in nums will appear twice, only two integers will appear once.
Hint 1
XOR of everything gives a ^ b. How can you separate a from b?
Hint 2
Pick a bit where a and b differ and split the array by it.
From brute force to the pattern: A set or counter is O(n) space; the XOR split is O(1).
Spot it: XOR cancels pairs, leaving a ^ b. Any set bit of it is a bit where a and b differ; split all numbers by that bit and XOR each group separately.
Why not another pattern? A hash set uses O(n) space.
Approach:
both = XOR of all.bit = both & −both(lowest set bit).- XOR the numbers with that bit set →
a;b = both ^ a.
class Solution:
def singleNumber(self, nums: List[int]) -> List[int]:
both = 0
for x in nums:
both ^= x # pairs cancel: a ^ b remains
bit = both & -both # lowest bit where a and b differ
a = 0
for x in nums:
if x & bit:
a ^= x # only one of the two singles has this bit
return [a, both ^ a]
What the code is doing, line by line:
x & −xisolates the lowest set bit (two's complement).- Each pair lands in the same group and cancels; the singles land in different groups.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Negative numbers.
- Zero as one of the answers.
- Two elements only.
Complexity: O(n) time, O(1) space.
Medium 204. Count Primes Google Amazon Microsoft
Problem: Count primes strictly less than n.
n = 104n = 00Constraints: 0 ≤ n ≤ 5 * 10⁶
Hint 1
Instead of testing each number, eliminate composites.
Hint 2
Each prime crosses out its multiples.
From brute force to the pattern: Trial division: O(n√n). Sieve: O(n log log n).
Spot it: Primality for every number below n → the Sieve of Eratosthenes: each prime crosses out its multiples starting at p².
Why not another pattern? Trial division for each number is O(n√n).
Approach:
is_prime = [True] * n; 0 and 1 are not prime.- For
pup to√n: if prime, markp², p² + p, …as not prime. - Count the remaining
Trues.
class Solution:
def countPrimes(self, n: int) -> int:
if n < 3:
return 0
is_prime = [True] * n
is_prime[0] = is_prime[1] = False
p = 2
while p * p < n:
if is_prime[p]:
is_prime[p * p::p] = [False] * len(range(p * p, n, p)) # cross out multiples
p += 1
return sum(is_prime)
What the code is doing, line by line:
- Multiples below
p²were already crossed out by smaller primes. - Slice assignment does the crossing out at C speed.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
n ≤ 2→ 0.n = 3→ 1.- Large n.
Complexity: O(n log log n) time, O(n) space.
8. Common mistakes
& 0xFFFFFFFF mask and a conversion back to signed.% MOD only at the end lets numbers grow to millions of digits and makes the code slow.// with negativesPython floors toward −∞ (-7 // 2 == -4). Problems that want truncation toward zero need int(a / b) or working with absolute values.int(n ** 0.5) can be off by one for large n; use math.isqrt.9. Self-check quiz
How many squarings does binary exponentiation need for n = 2,000,000,000?
Every number appears twice except one. Fastest O(1)-space way to find it?
Every number appears three times except one. What still works in O(1) space?
Which numbers have an odd number of divisors?
10. Practice list (in order)
| # | Problem | Level | Data structure | Twist |
|---|---|---|---|---|
| 202 | Happy Number | Easy | Solved in 04 · Fast & Slow Pointers: Implicit "next" = sum of digit squares | |
| 367 | Valid Perfect Square | Easy | Solved in 09 · Modified Binary Search: Binary search over candidate roots 1..num | |
| 50 | Pow(x, n) | Medium | Fast exponentiation: square the base, multiply it in when the current bit of n is 1 | |
| 260 | Single Number III | Medium | XOR all → a ^ b; its lowest set bit splits the numbers into two groups, one per answer | |
| 204 | Count Primes | Medium | Sieve of Eratosthenes: cross out multiples of each prime from p² | |
| 7 | Reverse Integer | Medium | Pop digits with % 10 and push with × 10; return 0 outside the 32-bit range | |
| 29 | Divide Two Integers | Medium | Subtract the largest shifted divisor (divisor << k) that fits, adding 1 << k to the quotient | |
| 137 | Single Number II | Medium | Count each bit position mod 3: the leftover bits form the single number | |
| 172 | Factorial Trailing Zeroes | Medium | Count factors of 5: n//5 + n//25 + n//125 + … | |
| 223 | Rectangle Area | Medium | Area A + area B − overlap; the overlap's width is max(0, min right − max left) | |
| 319 | Bulb Switcher | Medium | Bulb i is toggled once per divisor; only perfect squares have an odd count: answer ⌊√n⌋ | |
| 371 | Sum of Two Integers | Medium | XOR adds without carry, AND << 1 is the carry; repeat in 32-bit with a mask | |
| 372 | Super Pow | Medium | a^(10·x + d) = (a^x)^10 · a^d: process the exponent's digits left to right, mod 1337 | |
| 754 | Reach a Number | Medium | Walk right until the sum S ≥ |target| and S − target is even; flipping a step k changes S by 2k | |
| 866 | Prime Palindrome | Medium | Generate odd-length palindromes from their left halves in increasing order; test primality (even-length ones are divisible by 11) | |
| 1318 | Minimum Flips to Make a OR b Equal to c | Medium | Per bit: if c's bit is 1, need one of a/b set; if 0, flip every set bit of a and b | |
| 1344 | Angle Between Hands of a Clock | Medium | Minute hand 6° per minute; hour hand 30° per hour + 0.5° per minute; take the smaller angle | |
| 1492 | The kth Factor of n | Medium | Divisors come in pairs (d, n/d): list the small ones up to √n, then mirror | |
| 1680 | Concatenation of Consecutive Binary Numbers | Medium | Shift left by the bit length of i, OR in i, reduce mod 10⁹ + 7 | |
| 1922 | Count Good Numbers | Medium | 5 choices at even indices, 4 (primes) at odd indices: 5^⌈n/2⌉ · 4^⌊n/2⌋ with fast power | |
| 2396 | Strictly Palindromic Number | Medium | In base n − 2, every n ≥ 5 is written "12" (and 4 is "100" in base 2): never palindromic | |
| 3513 | Number of Unique XOR Triplets I | Medium | With a permutation of 1..n (n ≥ 3), every value below the next power of two is reachable | |
| 3702 | Longest Subsequence With Non-Zero Bitwise XOR | Medium | Total XOR ≠ 0 → n; all zeros → 0; otherwise drop one non-zero element → n − 1 | |
| 3896 | Minimum Operations to Transform Array into Alternating Prime | Medium | Sieve once; even index → distance to the next prime; odd index → 0, or 1 (2 for the value 2) if it's prime | |
| 1823 | Find the Winner of the Circular Game | Medium | Josephus recurrence: winner(i) = (winner(i − 1) + k) mod i, starting from winner(1) = 0 | |
| 318 | Maximum Product of Word Lengths | Medium | 26-bit mask per word; two words share no letters iff their masks AND to 0 | |
| 3514 | Number of Unique XOR Triplets II | Medium | Values ≤ 1500 means XORs fit in 11 bits: set of pair XORs, then XOR each with every value | |
| 3644 | Maximum K to Sort a Permutation | Medium | k = AND of all misplaced values (0 if already sorted) | |
| 3047 | Find the Largest Area of Square Inside Two Rectangles | Medium | For every pair, the intersection is a rectangle; the largest square side is min(width, height) | |
| 3648 | Minimum Sensors to Cover Grid | Medium | Each sensor covers a (2k+1)×(2k+1) square: ceil(n/(2k+1)) · ceil(m/(2k+1)) | |
| 779 | K-th Symbol in Grammar | Medium | Each step copies (0→01, 1→10): symbol k flips once per 1-bit of k−1, so the answer is popcount(k−1) mod 2 | |
| 2571 | Minimum Operations to Reduce an Integer to 0 | Medium | Walk the bits: a lone 1 is subtracted; a run of 1s is turned into one carry (add 1) | |
| 477 | Total Hamming Distance | Medium | Per bit: (count of 1s) × (count of 0s) pairs differ there | |
| 843 | Guess the Word | Hard | Guess the word that minimises the largest group of candidates sharing a match count; keep only consistent words | |
| 3312 | Sorted GCD Pair Queries | Hard | Pairs with gcd exactly g = C(multiples of g, 2) − pairs with gcd 2g, 3g, …; prefix sums + binary search | |
| 233 | Number of Digit One | Hard | Solved in 15 · Dynamic Programming Patterns: Count 1s per digit position from the high part, the current digit and the low part | |
| 2081 | Sum of k-Mirror Numbers | Hard | Generate base-10 palindromes in increasing order (from their halves) and keep those that are also base-k palindromes | |
| 829 | Consecutive Numbers Sum | Hard | k consecutive numbers starting at x sum to kx + k(k−1)/2: count k where (n − k(k−1)/2) is a positive multiple of k |
Worked solutions for the practice list
Problems already solved in section 7 link back up there, and rows marked "Solved in …" link to the page where that problem is worked through. Every other problem from the table is solved here.
Medium 2396. Strictly Palindromic Number Google
Problem: Is n palindromic in every base from 2 to n − 2?
n = 9falsen = 4falseConstraints: 4 ≤ n ≤ 10⁵
Hint 1
Write n in base n − 2.
Hint 2
Is there any n that passes?
From brute force to the pattern: Checking every base is O(n log n); the observation is constant time.
Spot it: A math observation: n = 1 · (n − 2) + 2, so in base n − 2 it's "12" for n ≥ 5, not a palindrome. n = 4 is "100" in base 2.
Why not another pattern? Converting to every base works but proves nothing; the answer is always false.
Approach:
- Return
False.
class Solution:
def isStrictlyPalindromic(self, n: int) -> bool:
return False # base n - 2 always gives "12" (for n >= 5); n = 4 is "100" in base 2
What the code is doing, line by line:
- For
n ≥ 5,n − 2 ≥ 3 > 2, so the digits are 1 and 2. - The only remaining case,
n = 4, fails in base 2.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
n = 4.n = 5.- Large n.
Complexity: O(1).
Medium 3896. Minimum Operations to Transform Array into Alternating Prime Google
Problem: Increment elements so that even indices hold primes and odd indices hold non-primes. Return the minimum number of increments.
nums = [1,2,3,4]3nums = [5,6,7,8]0Constraints: 1 ≤ nums.length ≤ 10⁵ · 1 ≤ nums[i] ≤ 10⁵
Hint 1
Each index can be handled on its own.
Hint 2
Precompute primes with a sieve and the next prime above each value.
Hint 3
What's the cheapest way to make a prime non-prime by incrementing?
From brute force to the pattern: Trial division while incrementing is O(n · gap · √M); the sieve makes each index O(1).
Spot it: Each element is independent. A sieve (plus a "next prime at or above x" table) answers even indices; an odd index only needs work if it's prime: x + 1 is non-prime unless x = 2 (3 is prime, so it takes 2 steps to 4).
Why not another pattern? Testing primality by trial division while incrementing is much slower than one sieve.
Approach:
- Sieve up to a bit above 10⁵ (the next prime after 10⁵ is 100003).
next_prime[v]from the top down.- Sum per index: even →
next_prime[x] − x; odd →0if not prime, else2ifx == 2, else1.
class Solution:
def minOperations(self, nums: List[int]) -> int:
LIMIT = max(nums) + 100 # a prime always appears within 100 above any value <= 10^5
is_prime = [True] * (LIMIT + 1)
is_prime[0] = is_prime[1] = False
p = 2
while p * p <= LIMIT:
if is_prime[p]:
is_prime[p * p::p] = [False] * len(range(p * p, LIMIT + 1, p))
p += 1
next_prime = [0] * (LIMIT + 2)
nxt = LIMIT + 1
for v in range(LIMIT, -1, -1):
if is_prime[v]:
nxt = v
next_prime[v] = nxt # smallest prime >= v
ops = 0
for i, x in enumerate(nums):
if i % 2 == 0:
ops += next_prime[x] - x # climb to a prime
elif is_prime[x]:
ops += 2 if x == 2 else 1 # x + 1 is even and > 2, except 2 + 1 = 3
return ops
What the code is doing, line by line:
- Increments only go up, so an even index needs the nearest prime at or above it.
- For an odd prime
x > 2,x + 1is even and greater than 2, hence composite. - Prime gaps below 10⁵ are under 100, so the sieve limit is safe.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Value 1 at an even index (next prime 2).
- Value 2 at an odd index (needs 2 steps).
- Already alternating → 0.
Complexity: O(M log log M + n) time, O(M) space.
Medium 7. Reverse Integer Start here Google Meta Amazon Microsoft Apple
Problem: Reverse the digits of a 32-bit signed integer; return 0 if the result overflows.
x = 123321x = -123-321Constraints: -2³¹ ≤ x ≤ 2³¹ - 1
Hint 1
Take digits from the end with % and //.
Hint 2
Watch for the 32-bit overflow.
From brute force to the pattern: String reversal is fine in Python; the digit loop is what C++/Java need.
Spot it: Digit arithmetic: x % 10 takes the last digit, x // 10 drops it, rev · 10 + d appends it. Work with |x| and restore the sign.
Why not another pattern? String reversal works in Python but hides the overflow reasoning interviewers ask about.
Approach:
sign,x = |x|.- While
x:rev = rev · 10 + x % 10,x //= 10. - Apply the sign; return 0 outside
[−2³¹, 2³¹ − 1].
class Solution:
def reverse(self, x: int) -> int:
sign = -1 if x < 0 else 1
x = abs(x)
rev = 0
while x:
rev = rev * 10 + x % 10 # move the last digit of x to the end of rev
x //= 10
rev *= sign
return rev if -2**31 <= rev <= 2**31 - 1 else 0
What the code is doing, line by line:
- Working with
abs(x)avoids Python's floor-division surprises with negatives. - In a 32-bit language, check
rev > (2³¹ − 1) // 10before multiplying.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Negative numbers.
- Trailing zeros (120 → 21).
- Overflow (1534236469 → 0).
Complexity: O(log x) time, O(1) space.
Medium 29. Divide Two Integers Google Meta Amazon
Problem: Divide without *, / or %, truncating toward zero; clamp to the 32-bit range.
dividend = 10, divisor = 33dividend = 7, divisor = -3-2Constraints: -2³¹ ≤ dividend, divisor ≤ 2³¹ - 1 · divisor != 0
Hint 1
Repeated subtraction is too slow. How can you subtract big multiples of the divisor quickly?
Hint 2
Use left shifts to double the divisor.
From brute force to the pattern: Subtracting one divisor at a time is O(quotient); shifting is O(32).
Spot it: Long division in binary: bit shifts double the divisor. From the largest divisor << k that fits, subtract and add 1 << k — each bit of the quotient decided once.
Why not another pattern? Repeated subtraction is O(quotient), up to 2³¹ steps.
Approach:
- Handle the sign; work with absolute values.
- For
kfrom 31 down to 0: if(b << k) ≤ a:a −= b << k,q += 1 << k. - Apply the sign and clamp.
class Solution:
def divide(self, dividend: int, divisor: int) -> int:
negative = (dividend < 0) != (divisor < 0)
a, b = abs(dividend), abs(divisor)
q = 0
for k in range(31, -1, -1):
if (b << k) <= a: # divisor * 2^k still fits
a -= b << k
q += 1 << k # this bit of the quotient is 1
q = -q if negative else q
return max(-2**31, min(2**31 - 1, q)) # only -2^31 / -1 overflows
What the code is doing, line by line:
- Trying shifts from large to small decides the quotient's bits from the top, like long division.
- Truncation toward zero comes from working with absolute values.
- The only overflow case is
−2³¹ / −1.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
−2³¹ / −1→ clamp.- Negative operands.
- Divisor larger than the dividend → 0.
Complexity: O(32) time, O(1) space.
Medium 137. Single Number II Google Amazon Microsoft
Problem: Every element appears three times except one, which appears once. Find it in O(n) time and O(1) space.
nums = [2,2,3,2]3nums = [0,1,0,1,0,1,99]99Constraints: 1 ≤ nums.length ≤ 3 * 10⁴ · -2³¹ ≤ nums[i] ≤ 2³¹ - 1 · Each element in nums appears exactly three times except for one element which appears once.
Hint 1
Look at one bit position at a time.
Hint 2
How many times does each bit appear among the tripled numbers?
From brute force to the pattern: A counter uses O(n) space; per-bit counting uses O(1).
Spot it: For each bit position, the triple elements contribute a multiple of 3 ones. So (count of ones) % 3 is exactly the single number's bit there.
Why not another pattern? A hash map works but uses O(n) space; XOR only cancels pairs, not triples.
Approach:
- For each of the 32 bits: count numbers with that bit set; if
count % 3, set the bit in the answer. - Fix the sign for negative numbers (bit 31).
class Solution:
def singleNumber(self, nums: List[int]) -> int:
result = 0
for b in range(32):
ones = sum((x >> b) & 1 for x in nums) # how many numbers have bit b set
if ones % 3:
result |= 1 << b # tripled numbers contribute multiples of 3
if result >= 2**31:
result -= 2**32 # bit 31 set: it's a negative number in 32-bit
return result
What the code is doing, line by line:
- Python's
>>on negatives sign-extends, and& 1reads the two's-complement bit correctly. - The final adjustment converts the 32-bit pattern back to a signed integer.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Negative single number.
- Zero as the single number.
- One element.
Complexity: O(32 · n) time, O(1) space.
Medium 172. Factorial Trailing Zeroes Google
Problem: Return the number of trailing zeros in n!.
n = 30n = 51Constraints: 0 ≤ n ≤ 10⁴
Hint 1
Where do trailing zeros come from?
Hint 2
Count how many factors of 5 appear in 1..n.
From brute force to the pattern: Computing n! is O(n) big multiplications; counting 5s is O(log n).
Spot it: Each trailing zero needs a factor 10 = 2 · 5, and 2s are plentiful, so count the 5s in 1..n (multiples of 25 give two, …).
Why not another pattern? Computing n! is huge; counting zeros of the number is wasteful.
Approach:
zeros = 0; whilen:n //= 5;zeros += n.
class Solution:
def trailingZeroes(self, n: int) -> int:
zeros = 0
while n:
n //= 5
zeros += n # multiples of 5, then of 25, 125, ...
return zeros
What the code is doing, line by line:
n // 5counts multiples of 5; dividing again counts multiples of 25 (an extra 5 each), and so on.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
n < 5→ 0.n = 25→ 6.- Large n.
Complexity: O(log₅ n) time, O(1) space.
Medium 223. Rectangle Area Google Microsoft
Problem: Return the total area covered by two axis-aligned rectangles.
ax1 = -3, ay1 = 0, ax2 = 3, ay2 = 4, bx1 = 0, by1 = -1, bx2 = 9, by2 = 245ax1 = -2, ay1 = -2, ax2 = 2, ay2 = 2, bx1 = -2, by1 = -2, bx2 = 2, by2 = 216Constraints: -10⁴ ≤ ax1 ≤ ax2 ≤ 10⁴ · -10⁴ ≤ ay1 ≤ ay2 ≤ 10⁴ · -10⁴ ≤ bx1 ≤ bx2 ≤ 10⁴ · -10⁴ ≤ by1 ≤ by2 ≤ 10⁴
Hint 1
Add the two areas. What did you count twice?
Hint 2
How do you compute the overlapping rectangle?
From brute force to the pattern: Grid counting is infeasible; inclusion–exclusion is constant time.
Spot it: Inclusion–exclusion: add both areas, subtract the intersection. The intersection's sides come from min of right edges and max of left edges.
Why not another pattern? Counting unit squares is impossible for coordinates up to 10⁴.
Approach:
w = max(0, min(ax2, bx2) − max(ax1, bx1)), same for height.- Return
areaA + areaB − w · h.
class Solution:
def computeArea(self, ax1: int, ay1: int, ax2: int, ay2: int, bx1: int, by1: int, bx2: int, by2: int) -> int:
overlap_w = max(0, min(ax2, bx2) - max(ax1, bx1)) # 0 if they don't overlap horizontally
overlap_h = max(0, min(ay2, by2) - max(ay1, by1))
area_a = (ax2 - ax1) * (ay2 - ay1)
area_b = (bx2 - bx1) * (by2 - by1)
return area_a + area_b - overlap_w * overlap_h # don't count the shared part twice
What the code is doing, line by line:
- The overlap is itself a rectangle, bounded by the inner edges.
- A negative width means no overlap;
max(0, …)handles it.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- No overlap.
- One inside the other.
- Touching edges (overlap 0).
Complexity: O(1).
Medium 319. Bulb Switcher Google Amazon
Problem: n bulbs start off; on round i every i-th bulb toggles. How many are on after n rounds?
n = 31n = 00Constraints: 0 ≤ n ≤ 10⁹
Hint 1
How many times is bulb k toggled?
Hint 2
Which numbers have an odd number of divisors?
From brute force to the pattern: Simulation is far too slow; the divisor-parity argument gives a formula.
Spot it: Bulb k is toggled once for each divisor of k. Divisors pair up (d, k/d) except for perfect squares → only perfect squares end up on.
Why not another pattern? Simulating is O(n log n) with n up to 10⁹.
Approach:
- Return
isqrt(n).
from math import isqrt
class Solution:
def bulbSwitch(self, n: int) -> int:
return isqrt(n) # 1, 4, 9, ... have an odd number of divisors
What the code is doing, line by line:
- An odd number of toggles leaves a bulb on.
isqrtcounts the perfect squares ≤ n exactly (no float rounding).
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
n = 0→ 0.- Perfect square n.
- Large n.
Complexity: O(log n) time, O(1) space.
Medium 371. Sum of Two Integers Google Meta Amazon Microsoft
Problem: Add two integers without using + or −.
a = 1, b = 23a = 2, b = 35Constraints: -1000 ≤ a, b ≤ 1000
Hint 1
What does XOR compute? What does AND compute?
Hint 2
In Python, integers are unbounded: mask to 32 bits.
From brute force to the pattern: Bit-by-bit addition with an explicit carry loop is the same idea, one bit at a time.
Spot it: Bitwise addition: a ^ b is the sum ignoring carries, (a & b) << 1 is the carries. Repeat until no carry. In Python, mask to 32 bits to emulate fixed-width integers.
Why not another pattern? sum([a, b]) sidesteps the point; the question is about the binary adder.
Approach:
mask = 0xFFFFFFFF.- While
b:a, b = (a ^ b) & mask, ((a & b) << 1) & mask. - Convert back: if
a > 0x7FFFFFFF, it's negative:~(a ^ mask).
class Solution:
def getSum(self, a: int, b: int) -> int:
mask = 0xFFFFFFFF # emulate 32-bit integers
a &= mask
b &= mask
while b:
a, b = (a ^ b) & mask, ((a & b) << 1) & mask # sum without carry, then the carry
return a if a <= 0x7FFFFFFF else ~(a ^ mask) # back to a signed value
What the code is doing, line by line:
- Each round moves the carries one position left; they disappear after at most 32 rounds.
~(a ^ mask)turns a 32-bit two's-complement pattern into Python's negative integer.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Negative numbers.
a = −b(result 0).- Zero.
Complexity: O(32) time, O(1) space.
Medium 372. Super Pow Google
Problem: Compute a^b mod 1337 where b is a huge number given as a digit array.
a = 2, b = [3]8a = 2, b = [1,0]1024Constraints: 1 ≤ a ≤ 2³¹ - 1 · 1 ≤ b.length ≤ 2000 · 0 ≤ b[i] ≤ 9 · b does not contain leading zeros.
Hint 1
How does a^(10x + d) relate to a^x?
Hint 2
Process the digits of b from left to right.
From brute force to the pattern: Converting b to an integer creates a 2000-digit number; the digit recurrence never does.
Spot it: Modular exponentiation digit by digit: appending digit d to the exponent turns r = a^x into r^10 · a^d (mod 1337).
Why not another pattern? Building b as an integer and calling pow works in Python, but the digit recurrence is the intended idea.
Approach:
result = 1.- For each digit
d:result = pow(result, 10, 1337) · pow(a, d, 1337) % 1337.
class Solution:
def superPow(self, a: int, b: List[int]) -> int:
MOD = 1337
result = 1
for d in b:
result = pow(result, 10, MOD) * pow(a, d, MOD) % MOD # exponent x -> 10x + d
return result
What the code is doing, line by line:
- If the exponent so far is
x, appendingdmakes it10x + d. a^(10x + d) = (a^x)^10 · a^d, all reducible mod 1337.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
amultiple of 1337 → 0.b = [0]style exponents.- Large a.
Complexity: O(len(b) · log 10) time, O(1) space.
Medium 754. Reach a Number Google
Problem: Step i moves i units left or right. Return the fewest steps to land exactly on target.
target = 23target = 32Constraints: -10⁹ ≤ target ≤ 10⁹ · target != 0
Hint 1
Go right every step until you reach or pass the target.
Hint 2
What happens to the total if you flip one step from right to left?
From brute force to the pattern: BFS on positions grows exponentially; the parity argument is O(√t).
Spot it: By symmetry use |target|. Take steps 1, 2, …, k all to the right until the sum reaches the target. Flipping step j subtracts 2j, so we need sum − target to be even — a parity argument.
Why not another pattern? BFS over positions explodes.
Approach:
t = |target|,k = 0,s = 0.- While
s < tor(s − t)is odd:k += 1,s += k. - Return
k.
class Solution:
def reachNumber(self, target: int) -> int:
t = abs(target) # left and right are symmetric
k = 0
s = 0
while s < t or (s - t) % 2:
k += 1
s += k # take one more step to the right
return k # flip steps worth (s - t) / 2 to land exactly
What the code is doing, line by line:
- Flipping a set of steps that sums to
(s − t)/2reduces the total by exactlys − t; any even surplus can be fixed. - An odd surplus can't be fixed by flips, so another step is needed.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Negative target.
- Target reached exactly by 1 + 2 + … + k.
- Target needing two extra steps.
Complexity: O(√|target|) time, O(1) space.
Hard 843. Guess the Word Google
Problem: Find the secret 6-letter word with Master.guess(word) (returns exact-position matches) within the allowed guesses.
secret = "acckzz", words = ["acckzz","ccbazz","eiowzz","abcczz"], allowedGuesses = 10You guessed the secret word correctly.secret = "hamada", words = ["hamada","khaled"], allowedGuesses = 10You guessed the secret word correctly.Constraints: 1 ≤ words.length ≤ 100 · words[i].length == 6 · words[i] consist of lowercase English letters. · All the strings of words are unique. · secret exists in words. · 10 ≤ allowedGuesses ≤ 30
Hint 1
After a guess returns k matches, which words can still be the secret?
Hint 2
Choose guesses that split the candidates as evenly as possible.
From brute force to the pattern: Guessing words one by one can take 100 guesses; the minimax filter needs about 10.
Spot it: Each guess partitions the candidates by match count; only the group matching the reply survives. Choosing the guess whose largest group is smallest (minimax) shrinks the candidates fastest. It's a counting/combinatorics game rather than a data-structure problem.
Why not another pattern? Random guesses usually work but can fail the strict tests; guessing in order fails easily.
Approach:
matches(a, b)= positions where letters agree.- Pick the candidate whose worst-case group (over match counts with all other candidates) is smallest.
- Guess it; if 6, done. Otherwise keep candidates with exactly the same match count to the guess.
from collections import Counter
class Solution:
def findSecretWord(self, words: List[str], master: "Master") -> None:
def matches(a, b):
return sum(x == y for x, y in zip(a, b))
candidates = words[:]
while candidates:
guess = min(candidates, key=lambda w: max(Counter(matches(w, o) for o in candidates).values())) # minimax
hit = master.guess(guess)
if hit == 6:
return
candidates = [w for w in candidates if matches(w, guess) == hit] # only words consistent with the reply
What the code is doing, line by line:
- The secret has exactly
hitmatches with the guess, so any word that doesn't is eliminated. - Minimising the largest group guarantees the most progress in the worst case.
- With 100 words, each round costs
O(n²)comparisons.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Two candidates.
- Words sharing many letters.
- The first guess is the secret.
Complexity: O(n² · 6) per guess, at most about 10 guesses.
Medium 866. Prime Palindrome Google
Problem: Return the smallest prime palindrome ≥ n.
n = 67n = 811Constraints: 1 ≤ n ≤ 10⁸
Hint 1
Which palindromes can never be prime?
Hint 2
Generate palindromes directly instead of scanning all numbers.
From brute force to the pattern: Scanning upward from n and checking each number takes too long near 10⁷; generating palindromes skips almost everything.
Spot it: Every even-length palindrome is divisible by 11, so only 11 and odd-length palindromes matter. Build them from a root (left half) in increasing order and test primality with trial division up to √x.
Why not another pattern? Testing every number upward hits the 10⁷–10⁸ gap with no 8-digit prime palindromes: too slow.
Approach:
- If
8 ≤ n ≤ 11, return 11. - For roots
1, 2, 3, …:x = int(root + reverse(root without its last digit)). - Return the first
x ≥ nthat is prime.
class Solution:
def primePalindrome(self, n: int) -> int:
def is_prime(x):
if x < 2:
return False
d = 2
while d * d <= x:
if x % d == 0:
return False
d += 1
return True
if 8 <= n <= 11:
return 11 # the only even-length prime palindrome
root = 1
while True:
s = str(root)
x = int(s + s[-2::-1]) # odd-length palindrome: 123 -> 12321
if x >= n and is_prime(x):
return x
root += 1
What the code is doing, line by line:
s[-2::-1]mirrors the root without repeating its last digit, giving odd length.- Roots in increasing order produce odd-length palindromes in increasing order.
- Even-length palindromes are multiples of 11 (alternating digit sum is 0), so only 11 itself can be prime.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
n = 1→ 2.nbetween 8 and 11 → 11.- Large n (answer 100030001).
Complexity: About O(√answer) per primality test over roughly 10⁴ roots.
Medium 1318. Minimum Flips to Make a OR b Equal to c Google
Problem: Return the minimum bit flips in a and b so that a | b == c.
a = 2, b = 6, c = 53a = 4, b = 2, c = 71Constraints: 1 ≤ a ≤ 10^9 · 1 ≤ b ≤ 10^9 · 1 ≤ c ≤ 10^9
Hint 1
Look at one bit position at a time.
Hint 2
What must a's and b's bits be for each value of c's bit?
From brute force to the pattern: Trying flip sets is exponential; bit-by-bit is O(31).
Spot it: Bits are independent → examine each bit position: c-bit 1 needs at least one 1; c-bit 0 needs both 0.
Why not another pattern? Trying flip combinations is exponential in the number of bits.
Approach:
- While any of a, b, c is non-zero: look at their lowest bits.
- c-bit 1: +1 if both a-bit and b-bit are 0. c-bit 0: + a-bit + b-bit.
- Shift all right.
class Solution:
def minFlips(self, a: int, b: int, c: int) -> int:
flips = 0
while a or b or c:
x, y, z = a & 1, b & 1, c & 1
if z:
flips += 1 if x == 0 and y == 0 else 0 # need at least one 1
else:
flips += x + y # both must become 0
a >>= 1
b >>= 1
c >>= 1
return flips
What the code is doing, line by line:
- OR works bit by bit, so each position is solved independently.
- Turning one 0 into 1 suffices when c needs a 1; when c needs 0, every 1 must go.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Already equal → 0.
- c = 0 (clear all bits).
- Both a and b have a 1 where c has 0 (two flips).
Complexity: O(log max(a, b, c)) time, O(1) space.
Medium 1344. Angle Between Hands of a Clock Google Meta Amazon Microsoft
Problem: Return the smaller angle (degrees) between the hour and minute hands at hour:minutes.
hour = 12, minutes = 30165hour = 3, minutes = 3075Constraints: 1 ≤ hour ≤ 12 · 0 ≤ minutes ≤ 59
Hint 1
How many degrees does each hand move per minute?
Hint 2
Don't forget the hour hand moves between hours.
From brute force to the pattern: Constant time either way; precision of the formulas is the point.
Spot it: Clock arithmetic: compute each hand's angle from 12 o'clock, take the difference and its complement to 360.
Why not another pattern? Forgetting that the hour hand moves during the hour is the common mistake.
Approach:
minute_angle = 6 · minutes.hour_angle = 30 · (hour % 12) + 0.5 · minutes.d = |h − m|; returnmin(d, 360 − d).
class Solution:
def angleClock(self, hour: int, minutes: int) -> float:
minute_angle = 6 * minutes # 360 / 60
hour_angle = 30 * (hour % 12) + 0.5 * minutes # also moves while the minutes pass
d = abs(hour_angle - minute_angle)
return min(d, 360 - d) # the smaller of the two angles
What the code is doing, line by line:
hour % 12maps 12 to 0.- The hour hand moves 30° per 60 minutes = 0.5° per minute.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- 12:00 → 0.
- Hands overlapping mid-hour.
- Angle > 180 (take 360 − d).
Complexity: O(1).
Medium 1492. The kth Factor of n Start here Google Amazon
Problem: Return the k-th smallest divisor of n, or −1.
n = 12, k = 33n = 7, k = 27Constraints: 1 ≤ k ≤ n ≤ 1000
Hint 1
Divisors come in pairs.
Hint 2
List the ones up to √n and derive the rest.
From brute force to the pattern: Scanning 1..n is O(n); the paired scan is O(√n).
Spot it: Divisors pair up around √n: collect d ≤ √n in order, their partners n/d come in reverse order → O(√n).
Why not another pattern? Checking all 1..n is O(n) (fine for 1000, but the √n idea is what's asked).
Approach:
small = [d for d ≤ √n if n % d == 0].large = [n // d for d in reversed(small) if d * d != n].- Return the k-th of
small + large, or −1.
class Solution:
def kthFactor(self, n: int, k: int) -> int:
small = []
d = 1
while d * d <= n:
if n % d == 0:
small.append(d)
d += 1
large = [n // d for d in reversed(small) if d * d != n] # partners, increasing
divisors = small + large
return divisors[k - 1] if k <= len(divisors) else -1
What the code is doing, line by line:
- Each
d ≤ √nthat dividesnhas a partnern/d ≥ √n. - A perfect square's root is its own partner, so it's not repeated.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- k larger than the divisor count → −1.
- Perfect squares.
- n prime.
Complexity: O(√n) time, O(√n) space for the divisors.
Medium 1680. Concatenation of Consecutive Binary Numbers Google Amazon
Problem: Concatenate the binary forms of 1..n; return the value mod 10⁹ + 7.
n = 11n = 327Constraints: 1 ≤ n ≤ 10⁵
Hint 1
Appending k bits to a number is a left shift by k.
Hint 2
When does the bit length of i increase?
From brute force to the pattern: String building is O(n log n) and needs big-integer conversion; shifting with mod is O(n).
Spot it: Appending i's bits means value = (value << bits(i)) | i. The bit length grows by one at each power of two (bit manipulation).
Why not another pattern? Building the binary string is O(n log n) characters and a huge number.
Approach:
bits = 0; foriin1..n: ifiis a power of two (i & (i − 1) == 0),bits += 1.value = ((value << bits) | i) % MOD.
class Solution:
def concatenatedBinary(self, n: int) -> int:
MOD = 10**9 + 7
value = 0
bits = 0
for i in range(1, n + 1):
if i & (i - 1) == 0:
bits += 1 # a power of two: one more binary digit
value = ((value << bits) | i) % MOD # append i's binary digits
return value
What the code is doing, line by line:
i & (i − 1) == 0is true exactly for powers of two.- Shifting left by
bitsmakes room fori, and OR writes it in.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
n = 1→ 1.- Powers of two.
- Large n (mod).
Complexity: O(n) time, O(1) space.
Medium 1922. Count Good Numbers Google Meta
Problem: Count digit strings of length n (up to 10¹⁵) with even digits at even indices and prime digits at odd indices (mod 10⁹ + 7).
n = 15n = 4400Constraints: 1 ≤ n ≤ 10¹⁵
Hint 1
How many choices does each position have?
Hint 2
Multiply them with fast exponentiation.
From brute force to the pattern: n multiplications vs log n.
Spot it: Positions are independent: multiply choices. With n up to 10¹⁵, use fast modular exponentiation.
Why not another pattern? Multiplying one position at a time is O(n).
Approach:
even = (n + 1) // 2,odd = n // 2.- Return
pow(5, even, MOD) · pow(4, odd, MOD) % MOD.
class Solution:
def countGoodNumbers(self, n: int) -> int:
MOD = 10**9 + 7
even_slots = (n + 1) // 2 # indices 0, 2, 4, ...: digits 0, 2, 4, 6, 8
odd_slots = n // 2 # indices 1, 3, 5, ...: digits 2, 3, 5, 7
return pow(5, even_slots, MOD) * pow(4, odd_slots, MOD) % MOD
What the code is doing, line by line:
- Each even index has 5 choices and each odd index 4, independently.
- Python's three-argument
powdoes binary exponentiation mod MOD.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
n = 1→ 5.- Huge n.
n = 4→ 400.
Complexity: O(log n) time, O(1) space.
Hard 3312. Sorted GCD Pair Queries Google Amazon
Problem: Sort the GCDs of all pairs; answer queries for the value at given indices.
nums = [2,3,4], queries = [0,2,2][1,2,2]nums = [4,4,2,1], queries = [5,3,1,0][4,2,1,1]Constraints: 2 ≤ n == nums.length ≤ 10⁵ · 1 ≤ nums[i] ≤ 5 * 10⁴ · 1 ≤ queries.length ≤ 10⁵ · 0 ≤ queries[i] < n * (n - 1) / 2
Hint 1
Count how many pairs have each gcd value instead of listing them.
Hint 2
Pairs where both numbers are multiples of g is easy to count. How do you turn that into gcd exactly g?
Hint 3
Use prefix sums over the gcd values and binary search for each query.
From brute force to the pattern: All pairs: O(n²). Counting by multiples: O(M log M).
Spot it: There are up to 5·10⁹ pairs, so count them by value. Pairs whose gcd is a multiple of g are C(m_g, 2) where m_g counts multiples of g. Subtract the counts for 2g, 3g, … (inclusion–exclusion from the top). Then prefix sums over g and a binary search per query.
Why not another pattern? Computing all pair GCDs is O(n²).
Approach:
freq[v]= occurrences ofv;m_g = Σ freq[g · t].- From
g = maxdown to 1:exact[g] = C(m_g, 2) − Σ exact[t · g]fort ≥ 2. prefix[g]= pairs with gcd ≤ g; answerqbybisect_right(prefix, q).
from bisect import bisect_right
from itertools import accumulate
class Solution:
def gcdValues(self, nums: List[int], queries: List[int]) -> List[int]:
top = max(nums)
freq = [0] * (top + 1)
for x in nums:
freq[x] += 1
exact = [0] * (top + 1) # pairs whose gcd is exactly g
for g in range(top, 0, -1):
m = sum(freq[g::g]) # numbers divisible by g
exact[g] = m * (m - 1) // 2 - sum(exact[2 * g::g]) # remove pairs with a larger gcd
prefix = list(accumulate(exact)) # prefix[g]: pairs with gcd <= g
return [bisect_right(prefix, q) for q in queries] # first g whose prefix exceeds q
What the code is doing, line by line:
- Both numbers of a pair are multiples of
gexactly whengdivides their gcd. - Going from large
gto small, the counts for multiples ofgare already exact, so subtracting them leaves gcd exactlyg. prefix[g]counts pairs at sorted positions0..prefix[g] − 1; the answer for indexqis the firstgwithprefix[g] > q.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Repeated values.
- All values coprime (every gcd is 1).
- Two elements.
Complexity: O(M log M + q log M) time (harmonic sums over M = max(nums)), O(M) space.
Medium 3513. Number of Unique XOR Triplets I Google Amazon Microsoft
Problem: nums is a permutation of 1..n. Count distinct values of nums[i] ^ nums[j] ^ nums[k] with i ≤ j ≤ k.
nums = [1,2]2nums = [3,1,2]4Constraints: 1 ≤ n == nums.length ≤ 10⁵ · 1 ≤ nums[i] ≤ n · nums is a permutation of integers from 1 to n.
Hint 1
Can a triplet use the same index more than once? What does x ^ y ^ y give?
Hint 2
Which values below the next power of two can you build from 1..n?
From brute force to the pattern: Triple loop: O(n³); the observation is constant time.
Spot it: A bit-manipulation observation: indices may repeat, so any single value x = x ^ y ^ y is reachable, and with 1..n available every number below 2^(bit length of n) can be formed for n ≥ 3. For n ≤ 2, the answer is n.
Why not another pattern? All triples are O(n³); even pairs-plus-one is O(n²).
Approach:
- If
n ≤ 2, returnn. - Otherwise return
1 << n.bit_length().
class Solution:
def uniqueXorTriplets(self, nums: List[int]) -> int:
n = len(nums)
if n <= 2:
return n # n = 1: {1}; n = 2: {1, 2}
return 1 << n.bit_length() # every value from 0 to 2^bits - 1 is reachable
What the code is doing, line by line:
- XOR never sets a bit above the highest bit of
n, so values stay below2^bits. - With 1, 2, 3 and the top power of two available, every combination below
2^bitsis reachable (0 = 1 ^ 2 ^ 3). - For n ≤ 2 there aren't enough values to reach the rest.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
n = 1→ 1.n = 2→ 2.na power of two.
Complexity: O(1) time and space.
Medium 3702. Longest Subsequence With Non-Zero Bitwise XOR Google
Problem: Return the length of the longest subsequence whose XOR is non-zero (0 if none).
nums = [1,2,3]2nums = [2,3,4]3Constraints: 1 ≤ nums.length ≤ 10⁵ · 0 ≤ nums[i] ≤ 10⁹
Hint 1
What if the XOR of the whole array is already non-zero?
Hint 2
If it's zero, what happens when you remove one element?
From brute force to the pattern: Checking subsequences is exponential; three cases cover everything.
Spot it: XOR reasoning: if the whole array's XOR is non-zero, take everything. If it's zero, removing any non-zero element x leaves XOR x ≠ 0. Only an all-zero array has no answer.
Why not another pattern? Subsequence DP over XOR values is far too big.
Approach:
total = XOR of all.total ≠ 0→n; all zeros → 0; elsen − 1.
from functools import reduce
from operator import xor
class Solution:
def longestSubsequence(self, nums: List[int]) -> int:
if reduce(xor, nums) != 0:
return len(nums) # the whole array works
if not any(nums):
return 0 # every subsequence XORs to 0
return len(nums) - 1 # removing one non-zero x leaves XOR x
What the code is doing, line by line:
- XOR of everything except
xequalstotal ^ x = xwhentotal = 0. - A subsequence of only zeros always XORs to 0.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- All zeros → 0.
- One non-zero element.
- Total XOR is zero.
Complexity: O(n) time, O(1) space.
Medium 1823. Find the Winner of the Circular Game Meta Amazon Microsoft
Problem: n friends in a circle; repeatedly count k and remove that friend. Return the winner (1-indexed).
n = 5, k = 23n = 6, k = 51Constraints: 1 ≤ k ≤ n ≤ 500
Hint 1
After one removal, the game is the same with one fewer person. How are positions renumbered?
Hint 2
Write the Josephus recurrence.
From brute force to the pattern: List simulation is O(n²); the recurrence is O(n).
Spot it: The Josephus problem. After the first removal the game restarts with n − 1 people, shifted by k, so the winner's position follows the recurrence J(i) = (J(i − 1) + k) mod i.
Why not another pattern? Simulating with a list is O(n²) (or O(nk) with a queue).
Approach:
pos = 0(with one person, the winner is at index 0).- For
ifrom 2 ton:pos = (pos + k) % i. - Return
pos + 1.
class Solution:
def findTheWinner(self, n: int, k: int) -> int:
pos = 0 # winner's 0-based position with 1 person
for i in range(2, n + 1):
pos = (pos + k) % i # adding a person shifts everyone by k
return pos + 1
What the code is doing, line by line:
- With
ipeople, removing thek-th leavesi − 1people starting just after it, i.e. everyone's position shifted byk. - Undoing that shift from 1 person up to
ngives the winner's original seat.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
k = 1→ n.n = 1→ 1.klarger than n.
Complexity: O(n) time, O(1) space.
Medium 318. Maximum Product of Word Lengths Amazon
Problem: Return the maximum len(a) · len(b) over pairs of words with no common letters.
words = ["abcw","baz","foo","bar","xtfn","abcdef"]16words = ["a","ab","abc","d","cd","bcd","abcd"]4Constraints: 2 ≤ words.length ≤ 1000 · 1 ≤ words[i].length ≤ 1000 · words[i] consists only of lowercase English letters.
Hint 1
How can you test "no common letters" in O(1)?
Hint 2
Use a 26-bit mask per word.
From brute force to the pattern: Pairwise string checks are O(n² L); masks make each check O(1).
Spot it: Represent each word's letters as a bitmask; "no common letters" becomes mask_a & mask_b == 0, an O(1) check.
Why not another pattern? Comparing letter sets pairwise as strings is O(n² · L).
Approach:
- Mask per word (keep the longest word per mask).
- For every pair of masks with
a & b == 0, update the product.
class Solution:
def maxProduct(self, words: List[str]) -> int:
longest = {} # letter mask -> longest word length with exactly those letters
for w in words:
mask = 0
for ch in w:
mask |= 1 << (ord(ch) - 97)
longest[mask] = max(longest.get(mask, 0), len(w))
best = 0
items = list(longest.items())
for i, (m1, l1) in enumerate(items):
for m2, l2 in items[i + 1:]:
if m1 & m2 == 0:
best = max(best, l1 * l2) # no shared letters
return best
What the code is doing, line by line:
- Words with the same letter set only need their longest representative.
- A bitwise AND is zero exactly when no letter is shared.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- No valid pair → 0.
- Words with repeated letters.
- Many words with the same letters.
Complexity: O(Σ L + m²) time for m distinct masks, O(m) space.
Medium 3514. Number of Unique XOR Triplets II Amazon
Problem: Count distinct values of nums[i] ^ nums[j] ^ nums[k] with i ≤ j ≤ k.
nums = [1,3]2nums = [6,7,8,9]4Constraints: 1 ≤ nums.length ≤ 1500 · 1 ≤ nums[i] ≤ 1500
Hint 1
How large can a XOR of values up to 1500 be?
Hint 2
Compute all pair XORs first, then combine with a third value.
From brute force to the pattern: Triple loops: O(n³); two set steps: O(V²).
Spot it: XORs of values ≤ 1500 stay below 2048, so sets of results are tiny. Build the set of pair XORs (i ≤ j, so x ^ x = 0 is included), then XOR each with every value — bit manipulation with small sets instead of triple loops over indices.
Why not another pattern? Triple loops over 1500 elements are 5·10⁸.
Approach:
vals = set(nums).pairs = {a ^ b for a, b in vals}(including a = b).triples = {p ^ c for p in pairs for c in vals}; return its size.
class Solution:
def uniqueXorTriplets(self, nums: List[int]) -> int:
vals = set(nums)
pairs = {a ^ b for a in vals for b in vals} # i <= j allows a == b (giving 0)
triples = {p ^ c for p in pairs for c in vals} # add the third element
return len(triples)
What the code is doing, line by line:
- Only distinct values matter, and indices may repeat, so pairs of values (including equal ones) cover all
i ≤ j. - Both sets have at most 2048 elements, so the final step is about 3 million operations.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- One element → 1.
- Duplicates.
- Values that are powers of two.
Complexity: O(V² + 2048 · V) time for V distinct values, O(2048) space.
Medium 3644. Maximum K to Sort a Permutation Amazon
Problem: Swaps are allowed only between values whose AND equals k. Return the largest k that lets you sort the permutation.
nums = [0,3,2,1]1nums = [0,1,3,2]2Constraints: 1 ≤ n == nums.length ≤ 10⁵ · 0 ≤ nums[i] ≤ n - 1 · nums is a permutation of integers from 0 to n - 1.
Hint 1
Which elements have to be swapped at all?
Hint 2
What does a swap's AND say about the bits of the values involved?
From brute force to the pattern: Testing each k by building swap graphs is slow; the AND of misplaced values is O(n).
Spot it: Every misplaced value must take part in a swap, and a swap's AND keeps only bits shared by both values, so k can't have a bit missing from any misplaced value: k ≤ AND of misplaced values. That bound is always achievable, so the answer is a one-line bit-manipulation formula.
Why not another pattern? Trying every k with a graph check is O(n²) or worse.
Approach:
- AND together every
nums[i]withnums[i] != i. - Return it (0 if nothing is misplaced).
from functools import reduce
from operator import and_
class Solution:
def sortPermutation(self, nums: List[int]) -> int:
misplaced = [x for i, x in enumerate(nums) if x != i]
return reduce(and_, misplaced) if misplaced else 0 # bits every moved value shares
What the code is doing, line by line:
- A value that must move is swapped at least once, so every bit of
kis in that value. - With
kequal to the common bits of all misplaced values, they can be sorted (checked against brute force on small cases).
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Already sorted → 0.
- Two values swapped.
- Misplaced values with no common bits → 0.
Complexity: O(n) time, O(1) space.
Medium 3047. Find the Largest Area of Square Inside Two Rectangles Cisco
Problem: Return the largest area of a square that fits inside the intersection of at least two of the axis-aligned rectangles.
bottomLeft = [[1,1],[2,2],[3,1]], topRight = [[3,3],[4,4],[6,6]]1bottomLeft = [[1,1],[1,3],[1,5]], topRight = [[5,5],[5,7],[5,9]]4Constraints: n == bottomLeft.length == topRight.length · 2 ≤ n ≤ 10³ · bottomLeft[i].length == topRight[i].length == 2 · 1 ≤ bottomLeft[i][0], bottomLeft[i][1] ≤ 10⁷ · 1 ≤ topRight[i][0], topRight[i][1] ≤ 10⁷ · bottomLeft[i][0] < topRight[i][0] · bottomLeft[i][1] < topRight[i][1]
Hint 1
Compute the intersection of two axis-aligned rectangles.
Hint 2
The largest square inside a rectangle has side min(width, height).
From brute force to the pattern: All pairs is already the intended O(n²) solution.
Spot it: Geometry: the intersection of two axis-aligned rectangles is a rectangle with width min(right) − max(left), height likewise. Its largest square has side min(w, h).
Why not another pattern? Grids or sweeps are unnecessary; with n ≤ 1000, checking all pairs is fast.
Approach:
- For every pair:
w = min(c) − max(a),h = min(d) − max(b). side = min(w, h); keep the largest positive side.- Return
side².
class Solution:
def largestSquareArea(self, bottomLeft: List[List[int]], topRight: List[List[int]]) -> int:
n = len(bottomLeft)
best = 0
for i in range(n):
for j in range(i + 1, n):
w = min(topRight[i][0], topRight[j][0]) - max(bottomLeft[i][0], bottomLeft[j][0])
h = min(topRight[i][1], topRight[j][1]) - max(bottomLeft[i][1], bottomLeft[j][1])
best = max(best, min(w, h)) # negative when they don't overlap
return best * best
What the code is doing, line by line:
- Overlap in each axis is "smaller right edge minus larger left edge".
- Intersections of more rectangles are smaller, so pairs are enough.
- A non-positive side means no square.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- No overlaps → 0.
- Touching edges (side 0).
- One rectangle inside another.
Complexity: O(n²) time, O(1) space.
Medium 3648. Minimum Sensors to Cover Grid Cisco
Problem: A sensor covers cells within Chebyshev distance k. Return the fewest sensors that cover an n × m grid.
n = 5, m = 5, k = 14n = 2, m = 2, k = 21Constraints: 1 ≤ n ≤ 10³ · 1 ≤ m ≤ 10³ · 0 ≤ k ≤ 10³
Hint 1
What shape does one sensor cover?
Hint 2
Treat rows and columns separately.
From brute force to the pattern: Greedy placement gives the same answer slowly; the formula is constant time.
Spot it: Chebyshev distance k is a (2k + 1)-wide square, and rows and columns are independent → tile each dimension: a math formula.
Why not another pattern? Placing sensors greedily cell by cell gives the same count but more work.
Approach:
side = 2k + 1.- Return
ceil(n / side) · ceil(m / side).
class Solution:
def minSensors(self, n: int, m: int, k: int) -> int:
side = 2 * k + 1 # width of the square one sensor covers
return (-(-n // side)) * (-(-m // side)) # ceil in each direction
What the code is doing, line by line:
- Covering a row of length
nwith intervals of lengthsideneedsceil(n / side). - A square cover is the product of a row cover and a column cover, and you can't do better since each sensor covers at most
siderows andsidecolumns.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- k = 0 → n · m.
- k large → 1.
- One row.
Complexity: O(1).
Hard 2081. Sum of k-Mirror Numbers Cisco
Problem: Return the sum of the n smallest numbers that are palindromes in base 10 and in base k.
k = 2, n = 525k = 3, n = 7499Constraints: 2 ≤ k ≤ 9 · 1 ≤ n ≤ 30
Hint 1
Which condition is easier to generate numbers for directly?
Hint 2
Generate base-10 palindromes in increasing order and test them in base k.
From brute force to the pattern: Checking every integer is hopeless; generating palindromes visits only about √X candidates.
Spot it: Checking every integer is too slow (the 30th can be in the billions). Generate only base-10 palindromes, in increasing order, from their first halves, and test the base-k representation — number-base arithmetic.
Why not another pattern? Scanning all integers up to ~10¹⁰ is far too slow.
Approach:
- For each length
L = 1, 2, …: for each half from10^(h−1)to10^h − 1, build the palindrome (odd lengths drop the middle repeat). - Convert to base
k; if it's a palindrome, add it. - Stop after
n.
class Solution:
def kMirror(self, k: int, n: int) -> int:
def base_k_palindrome(x):
digits = []
while x:
digits.append(x % k)
x //= k
return digits == digits[::-1]
total = found = 0
length = 1
while found < n:
half = (length + 1) // 2
for first in range(10 ** (half - 1), 10 ** half): # increasing halves -> increasing palindromes
s = str(first)
pal = int(s + s[::-1][length % 2:]) # mirror (skip the middle digit for odd length)
if base_k_palindrome(pal):
total += pal
found += 1
if found == n:
break
length += 1
return total
What the code is doing, line by line:
- For a fixed length, palindromes increase with their first half, so they're produced in order.
s[::-1][length % 2:]drops the repeated middle digit for odd lengths.- Base-10 palindromes are rare (about √N up to N), so the search is fast.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Single-digit numbers (all palindromes).
- Large k.
- n = 1.
Complexity: About O(√X · log X) for the largest answer X.
Medium 779. K-th Symbol in Grammar Microsoft
Problem: Row 1 is 0; each row replaces 0 with 01 and 1 with 10. Return the k-th symbol of row n.
n = 1, k = 10n = 2, k = 10Constraints: 1 ≤ n ≤ 30 · 1 ≤ k ≤ 2n ⁻ ¹
Hint 1
How is the symbol at position i related to its parent?
Hint 2
Count how many times it flips on the way from the root.
From brute force to the pattern: Building rows is O(2ⁿ); counting bits is O(log k).
Spot it: Symbol k (0-indexed k − 1) descends from its parent at (k − 1) // 2, flipped when it's a right child (odd index). Following the bits of k − 1 from the top, it flips once per 1-bit → bit manipulation.
Why not another pattern? Building row n needs 2^(n−1) symbols.
Approach:
- Return
bin(k − 1).count('1') % 2.
class Solution:
def kthGrammar(self, n: int, k: int) -> int:
return bin(k - 1).count("1") % 2 # one flip for every right turn on the way down
What the code is doing, line by line:
- A left child keeps its parent's symbol, a right child flips it.
- The path from the root to position
k − 1is given by its binary digits; each 1 is a right turn.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- k = 1 → 0.
- n = 1.
- Last position of a row.
Complexity: O(log k) time, O(1) space.
Medium 2571. Minimum Operations to Reduce an Integer to 0 Microsoft
Problem: Add or subtract any power of 2 per operation. Return the fewest operations to make n zero.
n = 393n = 543Constraints: 1 ≤ n ≤ 10⁵
Hint 1
Look at n in binary.
Hint 2
When is adding a power of two better than subtracting one?
From brute force to the pattern: BFS over integers is slow; the bit scan is O(log n).
Spot it: A bit manipulation greedy: scan from the lowest bit. A single 1 (next bit 0) costs one subtraction. A run of 1s (next bit also 1) is cheaper to clear by adding 1, which turns the run into one carry. This builds the non-adjacent form, which has the fewest non-zero digits.
Why not another pattern? BFS over values works but is far slower and unnecessary.
Approach:
- While
n: if the lowest bit is 1: if the next bit is also 1,n += 1, elsen −= 1; count an operation. - Shift right.
class Solution:
def minOperations(self, n: int) -> int:
ops = 0
while n:
if n & 1:
if n & 2:
n += 1 # a run of 1s: one carry clears the whole run
else:
n -= 1 # a lone 1: just subtract it
ops += 1
n >>= 1
return ops
What the code is doing, line by line:
- Adding 1 to
...0111gives...1000: one operation replaces the run. - A lone 1 can't be merged with anything, so subtracting it is best.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- Power of two → 1.
- All ones (2^k − 1) → 2.
- n = 1.
Complexity: O(log n) time, O(1) space.
Hard 829. Consecutive Numbers Sum Microsoft
Problem: Count the ways to write n as a sum of one or more consecutive positive integers.
n = 52n = 93Constraints: 1 ≤ n ≤ 10⁹
Hint 1
Write the sum of k consecutive numbers starting at x.
Hint 2
For which k does an integer x ≥ 1 exist?
From brute force to the pattern: All start/length pairs are O(n²); iterating k is O(√n).
Spot it: Math: a run of k numbers starting at x sums to k·x + k(k − 1)/2. For each length k, check whether n − k(k − 1)/2 is a positive multiple of k. Only k up to about √(2n) can fit.
Why not another pattern? Trying every start and length is O(n²).
Approach:
- For
k = 1, 2, …whilek(k − 1)/2 < n: - If
(n − k(k − 1)/2) % k == 0, count it.
class Solution:
def consecutiveNumbersSum(self, n: int) -> int:
ways = 0
k = 1
while k * (k - 1) // 2 < n: # the smallest run of length k is 1 + 2 + ... + k
if (n - k * (k - 1) // 2) % k == 0:
ways += 1 # x = (n - k(k-1)/2) / k is a positive integer
k += 1
return ways
What the code is doing, line by line:
x = (n − k(k − 1)/2) / kmust be a positive integer.- Once
k(k − 1)/2 ≥ n,xwould be ≤ 0, so the loop stops.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- n = 1 → 1.
- Powers of two (only the number itself).
- Large n.
Complexity: O(√n) time, O(1) space.
Medium 477. Total Hamming Distance Apple
Problem: Return the sum of Hamming distances over all pairs of numbers.
nums = [4,14,2]6nums = [4,14,4]4Constraints: 1 ≤ nums.length ≤ 10⁴ · 0 ≤ nums[i] ≤ 10⁹ · The answer for the given input will fit in a 32-bit integer.
Hint 1
Look at a single bit position across all numbers.
Hint 2
How many pairs differ at that bit?
From brute force to the pattern: All pairs: O(32 n²); per-bit counting: O(32 n).
Spot it: Bits are independent → look at one bit position at a time: with c ones among n numbers, exactly c · (n − c) pairs differ at that bit.
Why not another pattern? Comparing all pairs is O(n² · 32).
Approach:
- For each of 32 bits:
c= numbers with that bit set. - Add
c · (n − c).
class Solution:
def totalHammingDistance(self, nums: List[int]) -> int:
n = len(nums)
total = 0
for b in range(32):
ones = sum((x >> b) & 1 for x in nums) # numbers with bit b set
total += ones * (n - ones) # each (one, zero) pair differs here
return total
What the code is doing, line by line:
- A pair contributes 1 at bit
bexactly when one number has it and the other doesn't. - Summing over bits counts every differing bit of every pair.
Dry run: use the Step through the solution player under the code. It runs this exact code on Example 1 and shows every line with the variables at that moment.
Edge cases to test:
- All equal → 0.
- Two numbers.
- Zeros.
Complexity: O(32 · n) time, O(1) space.