PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

A Pinterest software-engineer coding screen: given positive 32-bit integers and a target, decide whether some subsequence with '+'/'*' operators evaluated strictly left to right (equal precedence) hits the target, and return a valid expression. The answer spans forward backtracking, monotonicity-based pruning, a divisibility-guided reverse search from the target, complexity analysis, and 32-bit overflow handling.

  • Medium
  • Pinterest
  • Coding & Algorithms
  • Software Engineer

Decide target via subsequence plus/multiply expression

Company: Pinterest

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: Medium

Interview Round: Technical Screen

##### Question Given a sequence of positive 32-bit integers `A` and an integer `target`, determine whether there exists a subsequence of `A` (preserving order, using each element at most once) and a placement of `+` and `*` operators between the chosen numbers such that, evaluating the expression strictly from left to right with **equal precedence** (i.e., `+` and `*` are applied in order, ignoring normal math precedence), the resulting value equals `target`. **Example:** For `A = [1, 9, 8, 7, 10, 3, 1]` and `target = 25`, one valid expression is `8*3+1` (evaluated left to right: `8*3 = 24`, then `24+1 = 25`). Implement a function that returns `true`/`false` and, if `true`, also returns one valid expression. Then discuss: 1. A backtracking / combinatorial search that builds a subsequence and enforces left-to-right evaluation **without** normal operator precedence. 2. Pruning heuristics to accelerate the search (e.g., stop a branch when the partial value already exceeds reasonable bounds, avoid revisiting equivalent states, and apply early-termination rules). 3. A reverse search starting from `target`, undoing operators with subtraction and division: continue a subtraction branch only while the remaining target stays `>= 0`, and take a division branch only when the current target is exactly divisible by the chosen number. Explain the correctness conditions and the order in which elements must be consumed. 4. The time and space complexity of your approach and its worst-case behavior. 5. How to handle 32-bit overflow of intermediate results, plus other edge cases. **Follow-up:** Propose additional pruning techniques to further accelerate the search.

Quick Answer: A Pinterest software-engineer coding screen: given positive 32-bit integers and a target, decide whether some subsequence with '+'/'*' operators evaluated strictly left to right (equal precedence) hits the target, and return a valid expression. The answer spans forward backtracking, monotonicity-based pruning, a divisibility-guided reverse search from the target, complexity analysis, and 32-bit overflow handling.

Given a sequence of positive 32-bit integers A and an integer target, determine whether there exists a non-empty subsequence of A and a placement of '+' and '*' operators between the chosen numbers such that the expression evaluates to target. The subsequence must preserve the original order, and each element may be used at most once. Operators are evaluated strictly from left to right with equal precedence, ignoring normal mathematical precedence. Return whether such an expression exists and, if it does, return one valid expression as a string with no spaces. If no expression exists, return an empty expression string.

Constraints

  • 0 <= len(A) <= 30
  • 1 <= A[i] <= 2^31 - 1
  • -2^31 <= target <= 2^31 - 1
  • The chosen subsequence must be non-empty.
  • Expressions are evaluated from left to right, so 2+3*4 evaluates as (2+3)*4 = 20.

Examples

Input: ([1, 9, 8, 7, 10, 3, 1], 25)

Expected Output: [True, '8*3+1']

Explanation: Choose the subsequence [8, 3, 1]. Left-to-right evaluation gives 8*3 = 24, then 24+1 = 25.

Input: ([2, 3, 4], 20)

Expected Output: [True, '2+3*4']

Explanation: With equal precedence, 2+3*4 is evaluated as (2+3)*4 = 20.

Input: ([], 7)

Expected Output: [False, '']

Explanation: The subsequence must be non-empty, so no expression can be formed from an empty list.

Input: ([10], 10)

Expected Output: [True, '10']

Explanation: A single chosen number is a valid expression, and it equals the target.

Input: ([2, 4, 6], 5)

Expected Output: [False, '']

Explanation: No non-empty subsequence with '+' and '*' evaluated left to right can produce 5.

Input: ([1, 1, 1], 3)

Expected Output: [True, '1+1+1']

Explanation: This tests duplicates and ones. Choosing all three numbers with addition gives 3.

Input: ([2147483647, 2], 2147483647)

Expected Output: [True, '2147483647']

Explanation: This tests a 32-bit boundary value. The first number alone equals the target.

Solution

def solution(A, target):
    if target <= 0 or not A:
        return [False, '']

    nums = list(A)
    n = len(nums)
    memo = {}

    def dfs(end, t):
        # Can we build a non-empty expression using only nums[0..end]
        # that evaluates to t?
        if end < 0 or t <= 0:
            return None

        key = (end, t)
        if key in memo:
            return memo[key]

        # Prefer a single-number expression when possible.
        for i in range(end, -1, -1):
            if nums[i] == t:
                memo[key] = str(nums[i])
                return memo[key]

        # Choose nums[i] as the last number in the expression.
        # Elements after i are skipped. Recursion uses only earlier elements.
        for i in range(end, -1, -1):
            x = nums[i]

            # Undo a final '+ x': previous value must be t - x.
            remaining = t - x
            if remaining > 0:
                prev_expr = dfs(i - 1, remaining)
                if prev_expr is not None:
                    memo[key] = prev_expr + '+' + str(x)
                    return memo[key]

            # Undo a final '* x': previous value must be exactly t / x.
            if x != 0 and t % x == 0:
                previous_value = t // x
                if previous_value > 0:
                    prev_expr = dfs(i - 1, previous_value)
                    if prev_expr is not None:
                        memo[key] = prev_expr + '*' + str(x)
                        return memo[key]

        memo[key] = None
        return None

    expression = dfs(n - 1, target)
    if expression is None:
        return [False, '']
    return [True, expression]

Time complexity: O(n * S), where S is the number of distinct memoized (end_index, remaining_target) states; in the worst case S can be exponential in n.. Space complexity: O(S + n), excluding the returned expression, where S is the number of memoized states and n is the recursion depth bound..

Hints

  1. Try working backward from target. If the last chosen number is x and the last operator was '+', the previous value must have been target - x.
  2. If the last operator was '*', the current target must be exactly divisible by x. Memoize states like (rightmost_allowed_index, remaining_target) to avoid repeating equivalent searches.
Last updated: Jun 23, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,000+ 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

  • Maximize Boxes Stored Through One Entrance - Pinterest (medium)
  • Solve Multiple Coding Interview Problems - Pinterest (medium)
  • Implement a Sparse Matrix Class - Pinterest (medium)
  • Assign Pins to Shortest Columns - Pinterest (medium)
  • Design Hierarchical Permission Checks - Pinterest (medium)