PracHub
QuestionsPremiumLearningGuidesCheatsheetNEW

Quick Overview

This question evaluates proficiency in combinatorial optimization and set-coverage with cost minimization, including handling case-insensitive service matching and enumerating minimal solution combinations.

  • Medium
  • Airbnb
  • Coding & Algorithms
  • Software Engineer

Compute minimum-cost service cover

Company: Airbnb

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: Medium

Interview Round: Technical Screen

You are given: ( 1) a list of rental service packages, where each package contains a set of services (strings) and a non-negative price, e.g., [(["wifi"], 50), (["parking"], 30), (["parking", "tv"], 70)]; and ( 2) a list of required services, e.g., ["WiFi", "parking"]. Design and implement an algorithm that returns (a) the minimum total cost to cover all required services (treat service names case-insensitively), and (b) the combination (s) of package indices that achieve this minimum. Define the output as: min_cost: int and combos: List[List[int]] where each inner list is a strictly increasing list of package indices; if coverage is impossible, return (-1, []). Explain and analyze your approach, including time and space complexity in terms of N (packages) and S (distinct required services). Describe how you will reconstruct the optimal combination (s) from your DP/bitmask state; handle ties and avoid duplicate combinations. Provide tests for the example above and at least one case with no feasible cover.

Quick Answer: This question evaluates proficiency in combinatorial optimization and set-coverage with cost minimization, including handling case-insensitive service matching and enumerating minimal solution combinations.

You are given a list of rental service packages and a list of required services. Each package is a pair (services, price), where services is a list of service names and price is a non-negative integer. Service names must be treated case-insensitively. Write a function that returns all minimum-cost ways to cover every distinct required service. Return a tuple (min_cost, combos): - min_cost: the minimum total price needed to cover all required services - combos: a list of package-index combinations that achieve min_cost Rules: - Package indices are 0-based. - Each combo must be a strictly increasing list of indices. - If multiple optimal combos exist, return all of them. - Do not return duplicate combos. - Ignore services in packages that are not required. - If coverage is impossible, return (-1, []). - For deterministic output, return combos sorted lexicographically. A strong solution should use DP with bitmasking over the distinct required services, then reconstruct all optimal combinations by following only transitions that preserve the optimal cost.

Constraints

  • 0 <= N <= 30, where N is the number of packages
  • 0 <= price <= 10^6 for each package
  • 0 <= S <= 15, where S is the number of distinct required services after case-insensitive normalization
  • The number of optimal combinations can be exponential in N, so reconstruction is inherently output-sensitive

Examples

Input: ([(["wifi"], 50), (["parking"], 30), (["parking", "tv"], 70)], ["WiFi", "parking"])

Expected Output: (80, [[0, 1]])

Explanation: Package 0 covers wifi and package 1 covers parking for a total of 80. Package 2 does not include wifi, so using it with package 0 costs 120 and is not optimal.

Input: ([(["wifi"], 50), (["tv"], 20)], ["wifi", "parking"])

Expected Output: (-1, [])

Explanation: No package provides parking, so it is impossible to cover all required services.

Input: ([(["a"], 5), (["b"], 5), (["a", "b"], 10)], ["A", "B"])

Expected Output: (10, [[0, 1], [2]])

Explanation: Either buy packages 0 and 1 for 10 total, or package 2 alone for 10. Both are optimal.

Input: ([(["wifi"], 50)], [])

Expected Output: (0, [[]])

Explanation: No services are required, so the minimum cost is 0 and the empty combination is optimal.

Input: ([(["WiFi", "wifi"], 10), (["PARKING"], 20), (["wifi", "parking"], 40)], ["wifi", "WiFi", "Parking"])

Expected Output: (30, [[0, 1]])

Explanation: Required services normalize to wifi and parking. Package 0 covers wifi for 10, package 1 covers parking for 20, so the best total is 30.

Solution

def solution(packages, required):
    normalized_required = []
    seen = set()
    for name in required:
        key = str(name).lower()
        if key not in seen:
            seen.add(key)
            normalized_required.append(key)

    s = len(normalized_required)
    bit_index = {name: i for i, name in enumerate(normalized_required)}

    n = len(packages)
    masks = [0] * n
    prices = [0] * n

    for i, (services, price) in enumerate(packages):
        prices[i] = price
        mask = 0
        local_seen = set()
        for service in services:
            key = str(service).lower()
            if key in bit_index and key not in local_seen:
                mask |= 1 << bit_index[key]
                local_seen.add(key)
        masks[i] = mask

    full_mask = (1 << s) - 1
    INF = 10 ** 18
    dp = [[INF] * (1 << s) for _ in range(n + 1)]
    dp[n][0] = 0

    for i in range(n - 1, -1, -1):
        pkg_mask = masks[i]
        price = prices[i]
        next_row = dp[i + 1]
        row = dp[i]
        for rem in range(1 << s):
            best = next_row[rem]
            new_rem = rem & ~pkg_mask
            take_cost = price + next_row[new_rem]
            if take_cost < best:
                best = take_cost
            row[rem] = best

    min_cost = dp[0][full_mask]
    if min_cost >= INF:
        return (-1, [])

    combos = []
    path = []

    def dfs(i, rem):
        if i == n:
            if rem == 0:
                combos.append(path.copy())
            return

        best = dp[i][rem]

        if dp[i + 1][rem] == best:
            dfs(i + 1, rem)

        new_rem = rem & ~masks[i]
        if prices[i] + dp[i + 1][new_rem] == best:
            path.append(i)
            dfs(i + 1, new_rem)
            path.pop()

    dfs(0, full_mask)
    combos.sort()
    return (min_cost, combos)

Time complexity: O(N * 2^S + T), where T is the total size of the reconstructed optimal output. Space complexity: O(N * 2^S + T).

Hints

  1. Map each distinct required service to a bit position. Then each package becomes a bitmask showing which required services it covers.
  2. Use DP on (package_index, remaining_services_mask) to compute the minimum cost, then run a DFS that follows only transitions whose cost matches the DP optimum to reconstruct all optimal combos.
Last updated: Apr 20, 2026

Loading coding console...

PracHub

Master your tech interviews with 7,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Determine Exact Layover Booking - Airbnb (medium)
  • Implement Text Layout and Query Parsing - Airbnb (easy)
  • Find smallest permutation under constraints - Airbnb (medium)
  • Compute board-game score from regions - Airbnb (medium)
  • Construct smallest number from I/D pattern - Airbnb (medium)