Facebook Pixel

2979. Most Expensive Item That Can Not Be Bought 🔒

Problem Description

You are given two distinct prime numbers primeOne and primeTwo.

Alice and Bob are visiting a market that has an infinite number of items. For any positive integer x, there exists an item with price x. Alice wants to buy items from the market to gift to Bob. She has an infinite number of coins in two denominations: primeOne and primeTwo.

The key constraint is that Alice can only pay using exact change - she can use any combination of her coins (including using just one type or both types), but she must pay the exact price of the item.

For example, if primeOne = 3 and primeTwo = 5:

  • She can buy an item priced at 3 (using one coin of value 3)
  • She can buy an item priced at 6 (using two coins of value 3)
  • She can buy an item priced at 8 (using one coin of value 3 and one coin of value 5)
  • But she cannot buy an item priced at 7 (no combination of 3s and 5s equals 7)

Your task is to find the most expensive item that Alice cannot buy. In other words, find the largest positive integer that cannot be expressed as a * primeOne + b * primeTwo where a and b are non-negative integers.

The solution uses the Chicken McNugget Theorem, which states that for two coprime positive integers (and distinct primes are always coprime), the largest number that cannot be expressed as their linear combination with non-negative coefficients is primeOne * primeTwo - primeOne - primeTwo.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

Let's think about what numbers Alice can make with her coins. If she has coins of value primeOne and primeTwo, she can make:

  • Any multiple of primeOne: primeOne, 2*primeOne, 3*primeOne, ...
  • Any multiple of primeTwo: primeTwo, 2*primeTwo, 3*primeTwo, ...
  • Any combination of both: a*primeOne + b*primeTwo where a, b ≥ 0

Since primeOne and primeTwo are distinct primes, they are coprime (their greatest common divisor is 1). This is a crucial property.

For small numbers, there will be gaps - numbers that cannot be formed. But as numbers get larger, we'll eventually be able to form all consecutive integers. Why? Because with two coprime numbers, we can eventually "fill in" all the gaps by using different combinations.

The key insight is that once we can form primeOne * primeTwo, we can form all larger numbers. Here's why:

  • From primeOne * primeTwo onwards, we can form consecutive sequences of length primeOne by adding multiples of primeOne
  • We can also form consecutive sequences of length primeTwo by adding multiples of primeTwo
  • Since primeOne and primeTwo are coprime, these sequences will eventually overlap and cover all integers

The largest number we cannot form turns out to be exactly primeOne * primeTwo - primeOne - primeTwo. This is known as the Frobenius number for two coprime integers.

To see why this specific formula works, consider that:

  • Numbers of the form k * primeOne where k ≥ primeTwo can be rewritten using primeTwo as well
  • Similarly for numbers of the form k * primeTwo where k ≥ primeOne
  • The "crossover point" where we can start forming everything is related to primeOne * primeTwo
  • The largest gap before this point is exactly primeOne * primeTwo - primeOne - primeTwo

Learn more about Math and Dynamic Programming patterns.

Solution Approach

The solution directly applies the Chicken McNugget Theorem (also known as the Frobenius coin problem for two coins).

For two coprime positive integers a and b, the theorem states that the largest number that cannot be expressed as a non-negative integer linear combination xa + yb (where x, y ≥ 0) is exactly a * b - a - b.

Since our inputs primeOne and primeTwo are distinct prime numbers, they are guaranteed to be coprime (their greatest common divisor is 1). This means we can directly apply the theorem.

Implementation:

The solution is remarkably simple - just one line of calculation:

def mostExpensiveItem(self, primeOne: int, primeTwo: int) -> int:
    return primeOne * primeTwo - primeOne - primeTwo

Why this formula works:

  1. Any number n ≥ primeOne * primeTwo can be expressed as xa + yb for some non-negative integers x and y
  2. The number primeOne * primeTwo - primeOne - primeTwo cannot be expressed this way
  3. This is the largest such number that cannot be expressed

Example walkthrough:

If primeOne = 3 and primeTwo = 5:

  • The formula gives us: 3 * 5 - 3 - 5 = 15 - 3 - 5 = 7
  • Indeed, 7 cannot be formed using any combination of 3s and 5s
  • All numbers from 8 onwards can be formed:
    • 8 = 3 + 5
    • 9 = 3 + 3 + 3
    • 10 = 5 + 5
    • 11 = 3 + 3 + 5
    • And so on...

The beauty of this solution is that it requires no loops, no dynamic programming, and no complex calculations - just a direct application of a mathematical theorem that gives us the answer in O(1) time and O(1) space.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a concrete example with primeOne = 2 and primeTwo = 7.

Step 1: Apply the formula According to the Chicken McNugget Theorem:

  • Most expensive item Alice cannot buy = 2 × 7 - 2 - 7 = 14 - 2 - 7 = 5

Step 2: Verify by checking what Alice CAN buy Let's enumerate what prices Alice can pay with combinations of 2-value and 7-value coins:

  • Price 1: Cannot buy (no combination works)
  • Price 2: Can buy (1 coin of value 2)
  • Price 3: Cannot buy (no combination works)
  • Price 4: Can buy (2 coins of value 2)
  • Price 5: Cannot buy (no combination of 2s and 7s equals 5)
  • Price 6: Can buy (3 coins of value 2)
  • Price 7: Can buy (1 coin of value 7)
  • Price 8: Can buy (4 coins of value 2)
  • Price 9: Can buy (1 coin of value 2 + 1 coin of value 7)
  • Price 10: Can buy (5 coins of value 2)
  • Price 11: Can buy (2 coins of value 2 + 1 coin of value 7)
  • Price 12: Can buy (6 coins of value 2)

Step 3: Confirm the pattern Notice that starting from price 6, we can form all consecutive integers:

  • 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ...

This happens because:

  • We can always add another 2-value coin to get the next even number
  • We can form any odd number ≥ 7 by using one 7-value coin plus some 2-value coins

Step 4: Verify our answer The numbers Alice cannot buy are: 1, 3, and 5. The largest of these is indeed 5, which matches our formula's result!

This demonstrates why the formula primeOne × primeTwo - primeOne - primeTwo gives us exactly the most expensive item that cannot be purchased.

Solution Implementation

1class Solution:
2    def mostExpensiveItem(self, primeOne: int, primeTwo: int) -> int:
3        """
4        Calculate the largest number that cannot be expressed as a non-negative
5        linear combination of two given prime numbers.
6      
7        This implements the Frobenius number formula for two coprime integers a and b:
8        Frobenius number = a * b - a - b
9      
10        Args:
11            primeOne: First prime number
12            primeTwo: Second prime number
13          
14        Returns:
15            The largest integer that cannot be represented as 
16            a non-negative combination of primeOne and primeTwo
17        """
18        # Apply the Frobenius number formula: (a * b) - a - b
19        # This gives the largest number that cannot be formed by adding
20        # non-negative multiples of the two prime numbers
21        return primeOne * primeTwo - primeOne - primeTwo
22
1class Solution {
2    /**
3     * Calculates the most expensive item that cannot be obtained
4     * using any combination of two given prime numbers.
5     * 
6     * This is based on the Chicken McNugget Theorem (Frobenius Coin Problem):
7     * For two coprime positive integers a and b, the largest number that
8     * cannot be expressed as ax + by (where x, y are non-negative integers)
9     * is ab - a - b.
10     * 
11     * @param primeOne The first prime number
12     * @param primeTwo The second prime number
13     * @return The largest value that cannot be obtained as a combination of the two primes
14     */
15    public int mostExpensiveItem(int primeOne, int primeTwo) {
16        // Apply the formula: (primeOne * primeTwo) - primeOne - primeTwo
17        // This gives us the largest number that cannot be represented
18        // as a linear combination of the two prime numbers
19        return primeOne * primeTwo - primeOne - primeTwo;
20    }
21}
22
1class Solution {
2public:
3    /**
4     * Calculates the most expensive item that cannot be purchased
5     * given two prime denominations (Chicken McNugget Theorem).
6     * 
7     * For two coprime positive integers, the largest number that
8     * cannot be expressed as their non-negative linear combination
9     * is given by: (primeOne * primeTwo - primeOne - primeTwo)
10     * 
11     * @param primeOne First prime number denomination
12     * @param primeTwo Second prime number denomination
13     * @return The largest number that cannot be formed using the two primes
14     */
15    int mostExpensiveItem(int primeOne, int primeTwo) {
16        // Apply the Frobenius formula for two coprime numbers
17        // Result represents the maximum unreachable value
18        int maxUnreachableValue = primeOne * primeTwo - primeOne - primeTwo;
19      
20        return maxUnreachableValue;
21    }
22};
23
1/**
2 * Calculates the maximum number of items that cannot be purchased
3 * given two prime numbers representing item prices.
4 * This implements the Frobenius number formula for two coprime integers.
5 * 
6 * @param primeOne - The first prime number representing an item price
7 * @param primeTwo - The second prime number representing an item price
8 * @returns The largest monetary amount that cannot be obtained using these two prices
9 */
10function mostExpensiveItem(primeOne: number, primeTwo: number): number {
11    // Apply the Frobenius number formula: (a * b) - a - b
12    // This gives the largest number that cannot be expressed as a linear combination
13    // of the two prime numbers with non-negative integer coefficients
14    return primeOne * primeTwo - primeOne - primeTwo;
15}
16

Time and Space Complexity

The time complexity is O(1) because the function performs a fixed number of arithmetic operations (one multiplication and two subtractions) regardless of the input values. These basic arithmetic operations take constant time.

The space complexity is O(1) because the function only uses a constant amount of extra space. It doesn't create any additional data structures or variables that grow with the input size - it simply computes and returns a single integer value directly.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Assuming the Formula Works for All Integer Pairs

The most critical pitfall is incorrectly applying this formula to non-coprime numbers. The Chicken McNugget Theorem only works when the two numbers are coprime (their GCD is 1).

Incorrect assumption:

def mostExpensiveItem(self, numOne: int, numTwo: int) -> int:
    # WRONG: This formula doesn't work if numOne and numTwo aren't coprime
    return numOne * numTwo - numOne - numTwo

Why it fails: If numOne = 6 and numTwo = 9 (both divisible by 3), the formula gives 6 * 9 - 6 - 9 = 39. However, you cannot form ANY number that isn't a multiple of 3 using these denominations. The actual answer would be infinity (or undefined) since infinitely many numbers cannot be formed.

Solution: While the problem guarantees distinct primes (which are always coprime), in a general implementation you should verify coprimality:

import math

def mostExpensiveItem(self, numOne: int, numTwo: int) -> int:
    if math.gcd(numOne, numTwo) != 1:
        # If not coprime, infinitely many numbers cannot be formed
        return -1  # or handle this case as specified
    return numOne * numTwo - numOne - numTwo

2. Misunderstanding the Problem Constraints

Some might think they need to handle the case where one of the coins has value 1:

Overcomplicated approach:

def mostExpensiveItem(self, primeOne: int, primeTwo: int) -> int:
    if primeOne == 1 or primeTwo == 1:
        return 0  # Every positive integer can be formed
    return primeOne * primeTwo - primeOne - primeTwo

Why it's unnecessary: The problem states we're given two distinct prime numbers. Since 1 is not a prime number, this check is redundant. The smallest possible inputs are 2 and 3.

3. Attempting Dynamic Programming or Iterative Solutions

Given the simplicity of the mathematical formula, implementing a complex solution is both inefficient and error-prone:

Overly complex approach:

def mostExpensiveItem(self, primeOne: int, primeTwo: int) -> int:
    # Unnecessary DP approach
    max_check = primeOne * primeTwo
    dp = [False] * max_check
    dp[0] = True
  
    for i in range(1, max_check):
        if i >= primeOne and dp[i - primeOne]:
            dp[i] = True
        if i >= primeTwo and dp[i - primeTwo]:
            dp[i] = True
  
    for i in range(max_check - 1, 0, -1):
        if not dp[i]:
            return i
    return 0

Why it's problematic: This uses O(n) time and space where n = primeOne * primeTwo, which is vastly inferior to the O(1) mathematical solution. It also introduces more opportunities for bugs.

4. Integer Overflow Concerns

For very large prime numbers, the multiplication might cause overflow in some languages:

Potential issue in languages with fixed integer sizes:

def mostExpensiveItem(self, primeOne: int, primeTwo: int) -> int:
    # In languages like C++ or Java, this might overflow
    return primeOne * primeTwo - primeOne - primeTwo

Solution: Python handles arbitrary precision integers automatically, but in other languages you might need to:

  • Use long/long long data types
  • Check for overflow before calculation
  • Rearrange the formula to minimize overflow risk: (primeOne - 1) * (primeTwo - 1) - 1

The rearranged formula is mathematically equivalent but performs subtraction before multiplication, reducing the maximum intermediate value.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

In a binary min heap, the minimum element can be found in:


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More