LeetCode 607: Sales Person Solution in Python – A Step-by-Step Guide

Imagine you’re a sales manager reviewing your team’s performance, and you need to find out which salespeople haven’t made any deals with a tricky client—let’s call them "RED." You’ve got records of salespeople, companies, and orders, and your job is to sift through them to spot the clean slates. That’s the core of LeetCode 607: Sales Person, an easy-level problem that’s all about filtering data across multiple tables. Using Python, we’ll explore two solutions: the Best Solution, a set-based filtering approach that mimics SQL joins for speed, and an Alternative Solution, a dictionary-based mapping that’s more explicit but slightly heavier. With detailed examples, beginner-friendly breakdowns—especially for the set method—and clear code, this guide will help you identify those salespeople, whether you’re new to coding or brushing up. Let’s dive into the sales data and start sorting!

What Is LeetCode 607: Sales Person?

In LeetCode 607: Sales Person, you’re given three tables:

  • SalesPerson: sales_id, name, salary, commission_rate, hire_date.
  • Company: com_id, name, city.
  • Orders: order_id, order_date, com_id, sales_id, amount.

Your task is to find the names of salespeople who have not made any sales to the company named "RED." For example, if a salesperson’s orders link to "RED" via the company ID, they’re out; if not, they’re in. This problem tests your ability to join and filter data, typically posed as an SQL query, but we’ll solve it in Python for a coding twist.

Problem Statement

  • Input: Three lists (or tables):
    • salesperson: [sales_id, name, ...].
    • company: [com_id, name, ...].
    • orders: [order_id, ..., com_id, sales_id, ...].
  • Output: List of names of salespeople with no sales to "RED."
  • Rules:
    • Match sales_id from SalesPerson to Orders.
    • Match com_id from Orders to Company.
    • Exclude salespeople linked to "RED."

Constraints

  • Each table has at least 1 row.
  • sales_id and com_id are unique within their tables.
  • Company names may repeat, but we filter by "RED" specifically.

Examples

  • Input:
  • ``` SalesPerson: sales_id | name | ... 1 | John | ... 2 | Amy | ... 3 | Mark | ... Company: com_id | name | ... 1 | RED | ... 2 | BLUE | ... Orders: order_id | com_id | sales_id | ... 1 | 1 | 1 | ... 2 | 2 | 2 | ... ```
    • Output: ["Amy", "Mark"] (John sold to RED)
  • Input:
  • ``` SalesPerson: [1,"Alice"], [2,"Bob"] Company: [1,"RED"], [2,"GREEN"] Orders: [1,1,1], [2,2,2] ```
    • Output: ["Bob"] (Alice sold to RED)

These examples set the stage—let’s solve it!

Understanding the Problem: Filtering Salespeople

To solve LeetCode 607: Sales Person in Python, we need to cross-reference three datasets to find salespeople not linked to "RED" via their orders. A naive approach might loop through every combination, but that’s slow. Instead, we’ll use:

  • Best Solution (Set-Based Filtering): O(n + m + p) time, O(n) space—fast and lean (n = salespeople, m = companies, p = orders).
  • Alternative Solution (Dictionary-Based Mapping): O(n + m + p) time, O(n + m) space—clear but heavier.

Let’s start with the set-based solution, breaking it down for beginners.

Best Solution: Set-Based Filtering with SQL-Like Logic

Why This Is the Best Solution

The set-based filtering approach is the top pick for LeetCode 607 because it’s efficient—O(n + m + p) time—and uses minimal space with sets, mimicking SQL’s LEFT JOIN and WHERE NOT IN. It quickly identifies "RED"-linked salespeople and excludes them, making it both fast and intuitive. It’s like checking a blacklist of RED sellers and picking everyone else!

How It Works

Think of this as sorting a sales roster:

  • Step 1: Find RED’s ID:
    • Scan company for "RED"’s com_id.
  • Step 2: Identify RED Sellers:
    • Scan orders, collect sales_ids linked to RED’s com_id in a set.
  • Step 3: Filter Salespeople:
    • Scan salesperson, include names where sales_id isn’t in the RED set.
  • Step 4: Return Result:
    • List of non-RED salespeople names.

It’s like a quick sales audit—blacklist and filter!

Step-by-Step Example

Example:

SalesPerson: [1,"John"], [2,"Amy"], [3,"Mark"]
Company: [1,"RED"], [2,"BLUE"]
Orders: [1,1,1], [2,2,2]
  • Step 1: RED’s com_id = 1.
  • Step 2: RED sellers:
    • Order [1,1,1]: sales_id = 1, set = {1}.
    • Order [2,2,2]: com_id = 2 (not RED), set = {1}.
  • Step 3: Filter:
    • ID 1 (John): In set, skip.
    • ID 2 (Amy): Not in set, include.
    • ID 3 (Mark): Not in set, include.
  • Output: ["Amy", "Mark"].

Code with Detailed Line-by-Line Explanation

Here’s the Python code, explained clearly:

class Solution:
    def salesPerson(self, salesperson: List[List], company: List[List], orders: List[List]) -> List[str]:
        # Step 1: Find RED's com_id
        red_id = None
        for com_id, name, *_ in company:
            if name == "RED":
                red_id = com_id
                break

        # Step 2: Collect sales_ids linked to RED
        red_sellers = set()
        for _, _, com_id, sales_id, *_ in orders:
            if com_id == red_id:
                red_sellers.add(sales_id)

        # Step 3: Filter salespeople not in red_sellers
        result = []
        for sales_id, name, *_ in salesperson:
            if sales_id not in red_sellers:
                result.append(name)

        # Step 4: Return result
        return result
  • Lines 4-8: Find RED’s com_id:
    • Loop through company, store com_id for "RED".
  • Lines 11-14: Build RED sellers set:
    • Loop through orders, add sales_id if com_id matches RED.
  • Lines 17-20: Filter:
    • Loop through salesperson, include names not in red_sellers.
  • Time Complexity: O(n + m + p)—one pass per list.
  • Space Complexity: O(n)—set of RED sellers.

This is like a sales blacklist—quick and clean!

Alternative Solution: Dictionary-Based Mapping

Why an Alternative Approach?

The dictionary-based mapping approach builds explicit mappings—O(n + m + p) time, O(n + m) space. It’s more verbose, tracking all sales per person, but it’s easier to visualize and extend (e.g., for multiple companies). It’s like keeping a detailed sales ledger!

How It Works

Picture this as a sales logbook:

  • Step 1: Map com_id to company name.
  • Step 2: Map sales_id to list of company names sold to.
  • Step 3: Check each salesperson for "RED" in their sales.
  • Step 4: Return names without "RED."

It’s like auditing each person’s sales history!

Step-by-Step Example

Example:

SalesPerson: [1,"John"], [2,"Amy"], [3,"Mark"]
Company: [1,"RED"], [2,"BLUE"]
Orders: [1,1,1], [2,2,2]
  • Step 1: com_map = {1: "RED", 2: "BLUE"}.
  • Step 2: Sales map:
    • ID 1: ["RED"].
    • ID 2: ["BLUE"].
    • ID 3: [].
  • Step 3: Filter:
    • John: "RED", skip.
    • Amy: No "RED", include.
    • Mark: No "RED", include.
  • Output: ["Amy", "Mark"].

Code for Dictionary Approach

class Solution:
    def salesPerson(self, salesperson: List[List], company: List[List], orders: List[List]) -> List[str]:
        # Step 1: Map com_id to company name
        com_map = {com_id: name for com_id, name, *_ in company}

        # Step 2: Map sales_id to companies sold to
        sales_map = {}
        for _, _, com_id, sales_id, *_ in orders:
            if sales_id not in sales_map:
                sales_map[sales_id] = set()
            sales_map[sales_id].add(com_map[com_id])

        # Step 3: Filter salespeople without RED
        result = []
        for sales_id, name, *_ in salesperson:
            if sales_id not in sales_map or "RED" not in sales_map[sales_id]:
                result.append(name)

        return result
  • Line 4: Build com_map.
  • Lines 7-10: Build sales_map with company names.
  • Lines 13-16: Include names if no "RED" in sales.
  • Time Complexity: O(n + m + p)—linear passes.
  • Space Complexity: O(n + m)—maps.

It’s a detailed sales check—thorough but heavier!

Comparing the Two Solutions

  • Set-Based (Best):
    • Pros: O(n + m + p) time, O(n) space, fast and lean.
    • Cons: Less extensible.
  • Dictionary (Alternative):
    • Pros: O(n + m + p) time, O(n + m) space, clear and flexible.
    • Cons: More memory.

Set-based wins for efficiency.

Additional Examples and Edge Cases

  • Input:
    • salesperson = [[1,"Alice"]], company = [[1,"RED"]], orders = []
    • Output: ["Alice"] (no sales).
  • Input:
    • salesperson = [[1,"Bob"]], company = [[1,"RED"]], orders = [[1,1,1]]
    • Output: [] (Bob sold to RED).

Both handle these well.

Complexity Breakdown

  • Set-Based: Time O(n + m + p), Space O(n).
  • Dictionary: Time O(n + m + p), Space O(n + m).

Set-based is optimal.

Key Takeaways

  • Set-Based: Quick filtering—smart!
  • Dictionary: Detailed mapping—clear!
  • Data: Joins are fun.
  • Python Tip: Sets rule—see Python Basics.

Final Thoughts: Spot Those Salespeople

LeetCode 607: Sales Person in Python is a neat data-filtering challenge. Set-based filtering offers speed and simplicity, while dictionary mapping gives a detailed view. Want more? Try LeetCode 182: Duplicate Emails or LeetCode 595: Big Countries. Ready to audit? Head to Solve LeetCode 607 on LeetCode and find those salespeople today!