Problem 1871

Abstract / Summary

Given a list of integers and a max jump distance, determine if you can reach a target index starting from position zero.

Note

The full problem description, including helpful examples, can be found on LeetCode.

Python 1871.py

class Solution:
    def findingUsersActiveMinutes(self, logs: List[List[int]], k: int) -> List[int]:
        active = defaultdict(set)
        for user, time in logs:
            active[user].add(time)

        result = [ 0 ] * k # one-based
        for a in active:
            minutes = len(active[a])
            if minutes <= k:
                result[minutes - 1] += 1 # one-based
        return result
12 lines | 420 bytes | submitted December 12, 2023 | GitHub   18% comment ratio | tab size 4 | low complexity

Difficulty

This problem is ranked as
easy medium hard

and has an acceptance rate of about 35% (300k+ submissions).
I solved 663 easy, 1250 medium and 309 hard problems

AI Disclaimer

Every single line of code was written by me, 100% from scratch, between August 2023 and August 2024.
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.

See this dedicated page for more details.
LeetCode profile | GitHub repo

Code Walkthrough

Overview

The provided implementation solves the problem of counting how many users have a specific number of distinct active minutes, limited to a maximum of k different minute values. It processes a list of log entries, each containing a user identifier and a timestamp measured in minutes, and returns an array where the i-th element (zero-based) represents the number of users whose activity spans exactly i + 1 distinct minutes.

Core Logic

The algorithm proceeds in three conceptual phases: data aggregation, result preparation, and final tallying.

Data Aggregation

A defaultdict of sets is created to map each user to the collection of unique minutes at which they performed an action. The use of a set automatically eliminates duplicate timestamps for the same user.

active = defaultdict(set)
for user, time in logs:
    active[user].add(time)

During this loop each (user, time) pair from the input logs is examined. The add operation on a set is constant-time on average, ensuring that the aggregation step scales linearly with the number of log entries.

Result Preparation

A list named result is allocated with a length equal to k, filled with zeros. This list will hold the final counts for each possible active-minute count from 1 to k.

result = [0] * k   # one-based indexing for the final answer

Pre-allocating the list avoids repeated resizing operations that would otherwise occur if the list were built incrementally.

Final Tallying

The algorithm iterates over the aggregated user data. For each user, it computes the number of distinct minutes by taking the length of the associated set. If this count does not exceed k, the corresponding bucket in result is incremented.

for a in active:
    minutes = len(active[a])
    if minutes <= k:
        result[minutes - 1] += 1   # adjust for zero-based index

The conditional check minutes <= k ensures that users with more than k distinct minutes are ignored, as they fall outside the required output range.

Finally, the populated result list is returned.

return result

Edge Cases Handled

The implementation gracefully manages several edge conditions without additional code.

When the input logs list is empty, the defaultdict remains empty, the subsequent loop over active does not execute, and the method returns a list of k zeros, correctly indicating that no users have any active minutes.

If a user appears multiple times with the same timestamp, the set structure automatically collapses those duplicates, so the count of distinct minutes reflects true activity diversity rather than raw log frequency.

When a user’s distinct minute count exceeds k, the conditional guard prevents any attempt to index beyond the bounds of the result list, thereby avoiding index errors and adhering to the specification that only counts up to k are required.

If k is larger than the maximum possible distinct minute count across all users, the extra slots in result simply remain zero, representing that no user achieved those higher counts.

Performance Optimizations

The code incorporates several choices that contribute to efficient execution.

Using a defaultdict(set) eliminates the need for explicit existence checks before inserting a minute value for a user. This reduces branching and keeps the inner loop tight.

Storing timestamps in a set rather than a list ensures that each insertion is amortized O(1) and that duplicate timestamps are filtered out instantly, avoiding a separate deduplication pass.

Pre-allocating the result list with a fixed size avoids dynamic resizing and repeated memory allocation that would occur if the list were grown incrementally.

The final counting loop accesses the length of each set directly, which is an O(1) operation, and updates the result array with a simple arithmetic index calculation, keeping the per-user overhead minimal.

Overall, the algorithm processes each log entry once, aggregates per-user data in constant-time structures, and produces the final counts in a single pass over the distinct users, resulting in a highly scalable solution.

written by openai gpt

ELI5 - Simplified Explanation

Imagine a big box of colorful building blocks where each block has a name on it. Some blocks have the same name because the same person picked them up at different times. The first part of this code acts like a helper who goes through all the logs and creates a separate pile for every person. Inside each person’s pile, the helper makes sure there is only one block for every unique minute that person was busy. If a person was busy at the same minute twice, the helper just keeps one block to stay organized.

Once all the piles are ready, the helper counts how many blocks are in each person’s pile. This tells everyone how many minutes that person was active. The code then prepares a set of slots lined up in a row, labeled one through k. For every person, the helper looks at the number of blocks in their pile and goes to the matching slot in the row to add a little tally mark. This keeps track of how many people were active for exactly one minute, two minutes, and so on, up to the number k. Everything ends up neatly sorted into those slots so it is easy to see the final tally of active users.

written by google gemini

Code Quality

Several LLMs ranked my code quality on a scale from 1 (very poor) to 10 (outstanding):
n = 27 | median = 8 | μ = 7.67 | σ = 0.98

Complexity Analysis

Time: linear
As a rule of thumb, the maximum input size for one second execution time is
  • factorial: up to 10 elements
  • exponential: up to 20 elements
  • polynomial: a few thousand elements
  • loglinear: up to 100,000 elements
  • linear: a few million elements
  • logarithmic: a billion elements
  • constant: practically unlimited
generated automatically

Other Solutions

I wrote a basic crawler to find other solutions to that problem.
Obviously, I did that after I solved the problem myself.

In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.

And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.

(click on a column header to sort the table)
author
author solutions
www AlgoMonster C++ Python Java TS
WalkCCC C++ Python Java
leetcode.ca C++ JS Python Java Go Rust TS
Progiez C++ Python Java
github black-shadows C++
charles-wangkai Java
everthis JS
fsq C++
JoshCrozier JS
lkwq007 Python
suxrobGM C#
wisdompeak C++
withaarzoo C++
AlgoMonster C++, Python, Java, TypeScript
WalkCCC C++, Python, Java
leetcode.ca C++, Go, Java, JavaScript, Python, Rust, TypeScript
Progiez C++, Java, Python
black-shadows C++, C++
charles-wangkai Java
everthis JavaScript
fsq C++
JoshCrozier JavaScript
lkwq007 Python
suxrobGM C#
wisdompeak C++
withaarzoo C++
26 links | 13 authors | 8 languages

Videos

5 videos   did my crawler come up with invalid videos ? drop me a line.

Similar Problems

4 similar problems

Solved On The Same Day

17 solutions   December 12, 2023

Extra

There are a few extra pages giving you some insights into my setup:
  • Tech Stack - my development environment and tools
  • AI - how AI helped me create this website (NOT solving the problems)
  • Progress - progression over time
  • Quality - code quality