Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1747. Leetflex Banned Accounts - Leetcode Solution

Problem Description

The "Leetflex Banned Accounts" problem involves identifying user accounts that should be banned based on certain criteria. You are given information about users and their activities on the Leetflex platform. Each user has a unique user_id, and you may be given additional details such as activity logs, login times, or ban reasons.

Your task is to process the provided data and return a list (or set) of user_ids that meet the ban criteria. The ban criteria might include factors such as repeated suspicious activity, logging in from multiple locations, or violating platform rules.

  • Each user should be banned at most once (do not reuse or duplicate user_ids in your output).
  • There is only one valid solution for the input provided.
  • Inputs may include arrays or lists of actions, timestamps, or other user data.

Return the list of banned user_ids in any order, as long as all and only the correct users are included.

Thought Process

To solve this problem, we need to carefully analyze the ban criteria and how user activity data is structured. A brute-force approach might involve checking every possible pair or combination of activities for every user, but this could be inefficient for large datasets.

Instead, we want to find a way to efficiently check if each user meets the ban conditions. For example, if the ban is based on repeated suspicious actions, we can count the number of such actions per user. If it's based on logging in from multiple locations, we can track the set of locations per user.

The key is to process the data in a way that allows us to quickly determine, for each user, whether they should be banned, without unnecessary repeated work. Using data structures like hash maps (dictionaries) allows us to group and count activities per user efficiently.

Our thought process is to:

  • Scan the activity data and organize it by user_id.
  • For each user, check if their activities meet the ban criteria.
  • Collect and return the user_ids that should be banned.

Solution Approach

Let's break down the solution step by step:

  1. Organize Activity Data:
    • Use a hash map (dictionary) to group activities by user_id.
    • This lets us easily access all activities for a given user in O(1) time.
  2. Check Ban Criteria:
    • For each user, examine their grouped activities.
    • Count or analyze the relevant features (e.g., number of suspicious actions, unique locations, etc.).
    • If the user meets the ban condition, add their user_id to the banned list.
  3. Return the Banned Users:
    • After processing all users, return the list or set of banned user_ids.
    • Order does not matter unless specified.

This approach is efficient because we only scan the data once and use fast lookups to group and check activities. Using hash maps is key for both grouping and counting, which keeps our solution scalable even for large datasets.

Example Walkthrough

Suppose we have the following activity log:

  • User 1: suspicious, suspicious, normal
  • User 2: normal, suspicious
  • User 3: suspicious, suspicious, suspicious

The ban criteria: Ban any user with at least 3 suspicious activities.

  1. Group activities by user:
    • User 1: 2 suspicious
    • User 2: 1 suspicious
    • User 3: 3 suspicious
  2. Check ban criteria:
    • User 1: Not banned (only 2 suspicious)
    • User 2: Not banned (only 1 suspicious)
    • User 3: Banned (3 suspicious)
  3. Return [3] as the list of banned user_ids.

This step-by-step process ensures we only ban users who meet the criteria, and efficiently checks each user.

Time and Space Complexity

Brute-force Approach:

  • Time Complexity: O(N * M), where N is the number of users and M is the number of activities per user, because you might check every activity for every user repeatedly.
  • Space Complexity: O(N + M), to store user groupings and activity data.
Optimized Approach:
  • Time Complexity: O(M), where M is the total number of activity records. We scan each activity once and group them by user.
  • Space Complexity: O(N + M), for the hash map grouping and storing results.

The optimized approach is much faster and more scalable, especially when the number of users or activities is large.

Summary

In this problem, we efficiently identify banned accounts by grouping user activities and checking each user against the ban criteria. Using hash maps allows us to quickly organize and analyze the data, avoiding slow nested loops. The solution is simple, scalable, and leverages core programming concepts like grouping, counting, and set operations.

The key insight is to process the data per user, using efficient data structures, to ensure each user is checked exactly once and only banned if they meet the criteria.

Code Implementation

def bannedAccounts(activities, threshold=3):
    from collections import defaultdict
    suspicious_count = defaultdict(int)
    for user_id, activity in activities:
        if activity == 'suspicious':
            suspicious_count[user_id] += 1
    return [user for user, count in suspicious_count.items() if count >= threshold]
      
#include <vector>
#include <string>
#include <unordered_map>
using namespace std;

vector<int> bannedAccounts(vector<pair<int, string>>& activities, int threshold = 3) {
    unordered_map<int, int> suspicious_count;
    for (auto& act : activities) {
        int user_id = act.first;
        string activity = act.second;
        if (activity == "suspicious") {
            suspicious_count[user_id]++;
        }
    }
    vector<int> result;
    for (auto& entry : suspicious_count) {
        if (entry.second >= threshold) {
            result.push_back(entry.first);
        }
    }
    return result;
}
      
import java.util.*;

public class Solution {
    public List<Integer> bannedAccounts(List<int[]> activities, int threshold) {
        Map<Integer, Integer> suspiciousCount = new HashMap<>();
        for (int[] act : activities) {
            int userId = act[0];
            String activity = act[1] == 1 ? "suspicious" : "normal";
            if (activity.equals("suspicious")) {
                suspiciousCount.put(userId, suspiciousCount.getOrDefault(userId, 0) + 1);
            }
        }
        List<Integer> result = new ArrayList<>();
        for (int userId : suspiciousCount.keySet()) {
            if (suspiciousCount.get(userId) >= threshold) {
                result.add(userId);
            }
        }
        return result;
    }
}
      
function bannedAccounts(activities, threshold = 3) {
    const suspiciousCount = {};
    for (const [userId, activity] of activities) {
        if (activity === 'suspicious') {
            suspiciousCount[userId] = (suspiciousCount[userId] || 0) + 1;
        }
    }
    const result = [];
    for (const userId in suspiciousCount) {
        if (suspiciousCount[userId] >= threshold) {
            result.push(Number(userId));
        }
    }
    return result;
}