LeetCode 597: Friend Requests I: Overall Acceptance Rate Solution in Python – A Step-by-Step Guide

Imagine you’re a social media analyst reviewing friend request logs—like requests [(1, 2), (1, 3), (2, 3)] and acceptances [(1, 2), (2, 3)]—and your task is to calculate the overall acceptance rate, such as 0.67 since 2 out of 3 requests were accepted. That’s the practical challenge of LeetCode 597: Friend Requests I: Overall Acceptance Rate, an easy-level problem that’s a fantastic way to practice data aggregation in Python. We’ll explore two solutions: the Best Solution, a set-based counting approach with division that’s efficient and clear, and an Alternative Solution, a brute-force traversal that’s thorough but less optimized. With detailed examples, clear code, and a friendly tone—especially for the set method—this guide will help you compute that rate, whether you’re new to coding or leveling up. Let’s tally those requests and start calculating!

What Is LeetCode 597: Friend Requests I: Overall Acceptance Rate?

In LeetCode 597: Friend Requests I: Overall Acceptance Rate, you’re given two lists of tuples: friend_requests where each tuple (sender_id, send_to_id) represents a friend request sent from one user to another, and request_accepted where each tuple (requester_id, accepter_id) represents an accepted request. Your task is to return the acceptance rate as a float, calculated as the number of unique accepted requests divided by the number of unique friend requests, rounded to 2 decimal places. If no requests exist, return 0.00. For example, with friend_requests = [(1,2), (1,3), (2,3)] and request_accepted = [(1,2), (2,3)], the result is 0.67 (2/3). This problem builds on LeetCode 349: Intersection of Two Arrays for set operations but focuses on ratio computation from paired data.

Problem Statement

  • Input:
    • friend_requests (List[Tuple[int, int]])—list of (sender_id, send_to_id).
    • request_accepted (List[Tuple[int, int]])—list of (requester_id, accepter_id).
  • Output: Float—acceptance rate (accepted/requests), rounded to 2 decimals.
  • Rules: Count unique requests and acceptances; return 0.00 if no requests.

Constraints

  • 1 <= friend_requests.length <= 10³
  • 1 <= request_accepted.length <= 10³
  • 1 <= sender_id, send_to_id, requester_id, accepter_id <= 10⁴

Examples

  • Input: friend_requests = [(1,2),(1,3),(2,3)], request_accepted = [(1,2),(2,3)]
    • Output: 0.67
    • Requests: 3 unique, Accepted: 2 unique, 2/3 ≈ 0.67.
  • Input: friend_requests = [(1,2),(2,1)], request_accepted = [(1,2)]
    • Output: 0.50
    • Requests: 2 unique, Accepted: 1 unique, 1/2 = 0.50.
  • Input: friend_requests = [], request_accepted = []
    • Output: 0.00
    • No requests, return 0.00.

Understanding the Problem: Calculating the Rate

To solve LeetCode 597: Friend Requests I: Overall Acceptance Rate in Python, we need to compute the ratio of unique accepted friend requests to unique total friend requests from two lists, handling up to 10³ records efficiently and returning a rounded float. A brute-force approach counting matches by scanning both lists repeatedly could work but is inefficient (O(n*m)). Instead, a set-based counting method processes each list in O(n) time, using sets to deduplicate requests and acceptances, then performs a simple division. We’ll explore:

  • Best Solution (Set-Based Counting with Division): O(n) time, O(n) space—fast and optimal (n = total records).
  • Alternative Solution (Brute-Force Traversal): O(n*m) time, O(n) space—thorough but slower (m = accepted records).

Let’s dive into the set solution with a friendly breakdown!

Best Solution: Set-Based Counting with Division

Why Sets Win

The set-based counting with division solution is the best for LeetCode 597 because it calculates the acceptance rate in O(n) time and O(n) space by converting both lists to sets to count unique requests and acceptances in a single pass, then dividing efficiently with a simple check for zero requests. It’s like tallying RSVPs and confirmations, counting each unique pair once, and figuring out the attendance rate—all in a quick, organized sweep!

How It Works

Think of this as a friend-request analyst:

  • Step 1: Build Sets:
    • Convert friend_requests to a set of tuples for unique requests.
    • Convert request_accepted to a set for unique acceptances.
  • Step 2: Count Uniques:
    • Total requests = size of request set.
    • Accepted requests = size of acceptance set.
  • Step 3: Compute Rate:
    • If total requests = 0, return 0.00.
    • Else, rate = accepted / total, round to 2 decimals.
  • Step 4: Return Result:
    • Acceptance rate as float.
  • Why It Works:
    • Sets deduplicate naturally, ensuring unique counts.
    • Single pass per list keeps it efficient.

It’s like an acceptance-rate calculating maestro!

Step-by-Step Example

Example: friend_requests = [(1,2),(1,3),(2,3)], request_accepted = [(1,2),(2,3)]

  • Step 1: Build sets:
    • Requests set: {(1,2), (1,3), (2,3)}.
    • Accepted set: {(1,2), (2,3)}.
  • Step 2: Count:
    • Total requests = 3.
    • Accepted = 2.
  • Step 3: Compute rate:
    • Rate = 2 / 3 ≈ 0.6667, round to 0.67.
  • Step 4: Return 0.67.
  • Result: 0.67.

Example: friend_requests = [(1,2),(2,1)], request_accepted = [(1,2)]

  • Step 1: Sets:
    • Requests: {(1,2), (2,1)}.
    • Accepted: {(1,2)}.
  • Step 2: Count:
    • Total = 2, Accepted = 1.
  • Step 3: Rate = 1 / 2 = 0.50.
  • Result: 0.50.

Code with Detailed Line-by-Line Explanation

Here’s the Python code, explained for beginners:

from typing import List, Tuple

class Solution:
    def findAcceptanceRate(self, friend_requests: List[Tuple[int, int]], request_accepted: List[Tuple[int, int]]) -> float:
        # Step 1: Convert lists to sets for unique counts
        total_requests = set(friend_requests)
        accepted_requests = set(request_accepted)

        # Step 2: Get sizes of unique requests and acceptances
        total_count = len(total_requests)
        accepted_count = len(accepted_requests)

        # Step 3: Compute acceptance rate
        if total_count == 0:
            return 0.00
        rate = accepted_count / total_count

        # Step 4: Return rounded result
        return round(rate, 2)
  • Lines 6-7: Convert lists to sets to deduplicate requests and acceptances.
  • Lines 10-11: Count unique elements in each set.
  • Lines 14-17: Compute rate:
    • Check for zero requests, return 0.00 if none.
    • Divide accepted by total, round to 2 decimals.
  • Time Complexity: O(n)—single pass per list to build sets.
  • Space Complexity: O(n)—set storage.

It’s like a friend-request rate wizard!

Alternative Solution: Brute-Force Traversal

Why an Alternative Approach?

The brute-force traversal approach counts accepted requests by scanning the acceptance list for each request, running in O(n*m) time (n = requests, m = acceptances) and O(n) space for storing unique requests. It’s thorough but inefficient, making it a good baseline for understanding or when avoiding sets.

How It Works

Picture this as a request-matching seeker:

  • Step 1: Get unique requests.
  • Step 2: For each request, check if accepted by scanning acceptances.
  • Step 3: Compute rate from counts.
  • Step 4: Return rounded rate.

It’s like a manual acceptance checker!

Step-by-Step Example

Example: friend_requests = [(1,2),(1,3)], request_accepted = [(1,2)]

  • Step 1: Unique requests: {(1,2), (1,3)}.
  • Step 2: Check:
    • (1,2): Found in acceptances, count = 1.
    • (1,3): Not found, count remains 1.
  • Step 3: Total = 2, Accepted = 1, Rate = 1/2 = 0.50.
  • Result: 0.50.

Code for Brute-Force Approach

from typing import List, Tuple

class Solution:
    def findAcceptanceRate(self, friend_requests: List[Tuple[int, int]], request_accepted: List[Tuple[int, int]]) -> float:
        # Step 1: Get unique requests
        unique_requests = set(friend_requests)
        total_count = len(unique_requests)

        # Step 2: Count accepted requests
        accepted_count = 0
        for req in unique_requests:
            for acc in request_accepted:
                if req == acc:
                    accepted_count += 1
                    break

        # Step 3: Compute rate
        if total_count == 0:
            return 0.00
        rate = accepted_count / total_count

        # Step 4: Return rounded result
        return round(rate, 2)
  • Lines 6-7: Deduplicate requests with set.
  • Lines 10-15: Count accepted by scanning acceptances for each request.
  • Lines 18-21: Compute and round rate.
  • Time Complexity: O(n*m)—nested loops.
  • Space Complexity: O(n)—set storage.

It’s a brute-force rate tallier!

Comparing the Two Solutions

  • Set-Based (Best):
    • Pros: O(n), O(n), fast and elegant.
    • Cons: Extra space for sets.
  • Brute-Force (Alternative):
    • Pros: O(n*m), O(n), explicit matching.
    • Cons: Slower, less efficient.

Set-based wins for speed!

Additional Examples and Edge Cases

  • Empty requests: 0.00.
  • All accepted: 1.00.
  • No acceptances: 0.00.

Set-based handles them all!

Complexity Recap

  • Set-Based: Time O(n), Space O(n).
  • Brute-Force: Time O(n*m), Space O(n).

Set-based’s the efficiency champ!

Key Takeaways

  • Set-Based: Rate finesse—learn at Python Basics!
  • Brute-Force: Scan simplicity.
  • Requests: Ratios are fun.
  • Python: Sets or loops, your pick!

Final Thoughts: Calculate That Rate!

LeetCode 597: Friend Requests I: Overall Acceptance Rate in Python is a practical data challenge. Set-based counting with division is your fast track, while brute-force offers a thorough dive. Want more? Try LeetCode 349: Intersection of Two Arrays or LeetCode 560: Subarray Sum Equals K. Ready to tally? Head to Solve LeetCode 597 on LeetCode and compute that acceptance rate today!