OAmaster
— / 20已做

The Stripe video platform is built on Jupyter. Requests are routed through multiple Jupyter servers; different developers are pinned to different servers based on load.

Implement route_request that accepts requests and routes them.

  • Part 1: Basic load balancing. For each incoming request, route to the server with the smallest active-request count. Tie → smaller index.
  • Part 2: Disconnection. Handle CONNECT and DISCONNECT actions; rebalance correctly when a connection drops.
  • Part 3: Sticky session by object id. Subsequent requests for the same object id route to the same server, unless that server is unhealthy.
  • Part 4: maxConnectionsPerTarget cap. When a target hits its cap, evict the least-recently-used object on that target.
  • Part 5: SHUTDOWN. When a target shuts down, re-route its evicted connections.
Working with 2 targets and high maxConnectionsPerTarget:
CONNECT, conn1, userA, obj1
CONNECT, conn2, userB, obj2
SHUTDOWN, 1
CONNECT, conn3, userC, obj3
→ conn1 userA 2, conn2 userB 2, conn1 userA 2, conn3 userC 1

解法

状态:每目标负载计数、每目标对象 LRU 表、obj_id → target 黏性映射、健康标记。route 读黏性映射(缺失或不健康时选负载最低的目标),更新 LRU,超容量时驱逐。disconnect 减负载。shutdown 翻健康标记,返回被驱逐的连接以重新路由。每次操作 O(n)n 为目标数(一般很小)。

from collections import OrderedDict, defaultdict

class LoadBalancer:
    def __init__(self, n_servers, max_per_target=float('inf')):
        self.n = n_servers
        self.loads = [0] * n_servers
        self.connections = defaultdict(set)
        self.obj_target = {}
        self.target_lru = [OrderedDict() for _ in range(n_servers)]
        self.max_per_target = max_per_target
        self.healthy = [True] * n_servers

    def _pick(self):
        best = (float('inf'), -1)
        for i in range(self.n):
            if self.healthy[i] and self.loads[i] < best[0]:
                best = (self.loads[i], i)
        return best[1]

    def route(self, conn_id, user, obj_id):
        target = self.obj_target.get(obj_id)
        if target is None or not self.healthy[target]:
            target = self._pick()
            self.obj_target[obj_id] = target
        lru = self.target_lru[target]
        if obj_id in lru:
            lru.move_to_end(obj_id)
        elif len(lru) >= self.max_per_target:
            evicted = next(iter(lru))
            del lru[evicted]
        lru[obj_id] = True
        self.connections[target].add(conn_id)
        self.loads[target] += 1
        return target

    def disconnect(self, conn_id, target):
        if conn_id in self.connections[target]:
            self.connections[target].remove(conn_id)
            self.loads[target] -= 1

    def shutdown(self, target):
        self.healthy[target] = False
        evicted = list(self.connections[target])
        self.connections[target].clear()
        self.loads[target] = 0
        return evicted
class LoadBalancer {
    int n, maxPerTarget;
    int[] loads;
    boolean[] healthy;
    Map<Integer, Set<String>> connections = new HashMap<>();
    Map<String, Integer> objTarget = new HashMap<>();
    List<LinkedHashMap<String, Boolean>> targetLRU;

    LoadBalancer(int n, int maxPerTarget) {
        this.n = n; this.maxPerTarget = maxPerTarget;
        loads = new int[n]; healthy = new boolean[n];
        targetLRU = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            healthy[i] = true;
            connections.put(i, new HashSet<>());
            targetLRU.add(new LinkedHashMap<>());
        }
    }

    int pick() {
        int best = -1, bestLoad = Integer.MAX_VALUE;
        for (int i = 0; i < n; i++)
            if (healthy[i] && loads[i] < bestLoad) { bestLoad = loads[i]; best = i; }
        return best;
    }

    int route(String connId, String user, String objId) {
        Integer target = objTarget.get(objId);
        if (target == null || !healthy[target]) {
            target = pick();
            objTarget.put(objId, target);
        }
        LinkedHashMap<String, Boolean> lru = targetLRU.get(target);
        if (lru.containsKey(objId)) lru.remove(objId);
        else if (lru.size() >= maxPerTarget) lru.remove(lru.keySet().iterator().next());
        lru.put(objId, true);
        connections.get(target).add(connId);
        loads[target]++;
        return target;
    }

    void disconnect(String connId, int target) {
        if (connections.get(target).remove(connId)) loads[target]--;
    }

    List<String> shutdown(int target) {
        healthy[target] = false;
        List<String> evicted = new ArrayList<>(connections.get(target));
        connections.get(target).clear();
        loads[target] = 0;
        return evicted;
    }
}
class LoadBalancer {
public:
    int n; size_t maxPerTarget;
    vector<int> loads;
    vector<bool> healthy;
    vector<unordered_set<string>> connections;
    unordered_map<string, int> objTarget;
    vector<list<string>> targetOrder;
    vector<unordered_map<string, list<string>::iterator>> targetIndex;

    LoadBalancer(int nServers, size_t maxPerTgt = SIZE_MAX)
        : n(nServers), maxPerTarget(maxPerTgt), loads(nServers, 0),
          healthy(nServers, true), connections(nServers),
          targetOrder(nServers), targetIndex(nServers) {}

    int pick() {
        int best = -1, bestLoad = INT_MAX;
        for (int i = 0; i < n; ++i)
            if (healthy[i] && loads[i] < bestLoad) { bestLoad = loads[i]; best = i; }
        return best;
    }

    int route(const string& connId, const string&, const string& objId) {
        int target;
        auto it = objTarget.find(objId);
        if (it == objTarget.end() || !healthy[it->second]) {
            target = pick();
            objTarget[objId] = target;
        } else target = it->second;
        auto& order = targetOrder[target];
        auto& idx = targetIndex[target];
        if (idx.count(objId)) { order.erase(idx[objId]); }
        else if (order.size() >= maxPerTarget) {
            idx.erase(order.front());
            order.pop_front();
        }
        order.push_back(objId);
        idx[objId] = prev(order.end());
        connections[target].insert(connId);
        loads[target]++;
        return target;
    }

    void disconnect(const string& connId, int target) {
        if (connections[target].erase(connId)) loads[target]--;
    }

    vector<string> shutdown(int target) {
        healthy[target] = false;
        vector<string> evicted(connections[target].begin(), connections[target].end());
        connections[target].clear();
        loads[target] = 0;
        return evicted;
    }
};

Given transactions_list, merchants_list, rules_list. Initialize each merchant's current_score = base_score. Apply rules in separate passes:

  1. If transaction.amount > rule.min_transaction_amount, multiply the merchant's score by rule.multiplicative_factor.
  2. If the same customer_id has made ≥ 3 transactions at this merchant (including the current one), add each matching rule's additive_factor to the merchant.
  3. If a transaction is the 3rd-or-later from the same customer at the same merchant within the same hour:
  • hour in [12, 17]: add penalty_each_time (also retroactively for the 1st and 2nd in the hour).
  • hour in [9, 11] or [18, 21]: subtract penalty_each_time.
  • else: no change.

Return comma-separated "merchant_id,score" strings in lexicographic merchant order.

解法

对交易三次独立扫描,依次更新商户分数。第 2 步用 (merchant, customer) 计数器跟终身交易,第 3 步用 (merchant, customer, hour) 跟小时交易。总复杂度 O(T · R)T 为交易数、R 为规则数。

from collections import defaultdict

def merchant_score(transactions, merchants, rules):
    score = {m["id"]: m["base_score"] for m in merchants}
    for t in transactions:
        for r in rules:
            if t["amount"] > r["min_transaction_amount"]:
                score[t["merchant_id"]] *= r["multiplicative_factor"]
    customer_count = defaultdict(int)
    for t in transactions:
        customer_count[(t["merchant_id"], t["customer_id"])] += 1
        if customer_count[(t["merchant_id"], t["customer_id"])] >= 3:
            for r in rules:
                score[t["merchant_id"]] += r["additive_factor"]
    hour_count = defaultdict(int)
    for t in transactions:
        h = t["hour"]
        hour_count[(t["merchant_id"], t["customer_id"], h)] += 1
        if hour_count[(t["merchant_id"], t["customer_id"], h)] >= 3:
            for r in rules:
                p = r["penalty_each_time"]
                if 12 <= h <= 17: score[t["merchant_id"]] += p
                elif (9 <= h <= 11) or (18 <= h <= 21): score[t["merchant_id"]] -= p
    return [f"{m},{score[m]}" for m in sorted(score)]
class Solution {
    static List<String> merchantScore(List<Map<String, Object>> transactions,
                                      List<Map<String, Object>> merchants,
                                      List<Map<String, Object>> rules) {
        Map<String, Double> score = new TreeMap<>();
        for (var m : merchants) score.put((String) m.get("id"), ((Number) m.get("base_score")).doubleValue());
        for (var t : transactions) {
            double amt = ((Number) t.get("amount")).doubleValue();
            String mid = (String) t.get("merchant_id");
            for (var r : rules)
                if (amt > ((Number) r.get("min_transaction_amount")).doubleValue())
                    score.merge(mid, ((Number) r.get("multiplicative_factor")).doubleValue(), (a, b) -> a * b);
        }
        Map<String, Integer> ccount = new HashMap<>();
        for (var t : transactions) {
            String key = t.get("merchant_id") + "|" + t.get("customer_id");
            int c = ccount.merge(key, 1, Integer::sum);
            if (c >= 3) {
                String mid = (String) t.get("merchant_id");
                for (var r : rules)
                    score.merge(mid, ((Number) r.get("additive_factor")).doubleValue(), Double::sum);
            }
        }
        Map<String, Integer> hcount = new HashMap<>();
        for (var t : transactions) {
            int h = ((Number) t.get("hour")).intValue();
            String key = t.get("merchant_id") + "|" + t.get("customer_id") + "|" + h;
            int c = hcount.merge(key, 1, Integer::sum);
            if (c >= 3) {
                String mid = (String) t.get("merchant_id");
                for (var r : rules) {
                    double p = ((Number) r.get("penalty_each_time")).doubleValue();
                    if (h >= 12 && h <= 17) score.merge(mid, p, Double::sum);
                    else if ((h >= 9 && h <= 11) || (h >= 18 && h <= 21)) score.merge(mid, -p, Double::sum);
                }
            }
        }
        List<String> out = new ArrayList<>();
        for (var e : score.entrySet()) out.add(e.getKey() + "," + e.getValue());
        return out;
    }
}
// Pseudo-C++ sketch — actual JSON-typed structs depend on the harness.
struct Transaction { string merchant_id, customer_id; double amount; int hour; };
struct Merchant { string id; double base_score; };
struct Rule { double min_transaction_amount, multiplicative_factor, additive_factor, penalty_each_time; };

vector<string> merchantScore(vector<Transaction>& transactions,
 vector<Merchant>& merchants,
 vector<Rule>& rules) {
 map<string, double> score;
 for (auto& m : merchants) score[m.id] = m.base_score;
 for (auto& t : transactions)
 for (auto& r : rules)
 if (t.amount > r.min_transaction_amount) score[t.merchant_id] *= r.multiplicative_factor;
 map<pair<string, string>, int> ccount;
 for (auto& t : transactions) {
 if (++ccount[{t.merchant_id, t.customer_id}] >= 3)
 for (auto& r : rules) score[t.merchant_id] += r.additive_factor;
 }
 map<tuple<string, string, int>, int> hcount;
 for (auto& t : transactions) {
 if (++hcount[{t.merchant_id, t.customer_id, t.hour}] >= 3) {
 for (auto& r : rules) {
 double p = r.penalty_each_time;
 if (t.hour >= 12 && t.hour <= 17) score[t.merchant_id] += p;
 else if ((t.hour >= 9 && t.hour <= 11) || (t.hour >= 18 && t.hour <= 21))
 score[t.merchant_id] -= p;
 }
 }
 }
 vector<string> out;
 for (auto& [m, s] : score) out.push_back(m + "," + to_string(s));
 return out;
}

Stripe Risk groups merchants based on shared link attributes. Given day1, day2, day3 batches of (merchant_id, link_type, link_duration, day) tuples, output per-day clusters.

Clustering rules. Two merchants are connected if they share an active link of the same link_type. A cluster is a connected component over active links.

Pinning rules. Each cluster has a pin = the merchant with the highest degree (ties → smallest merchant_id). When clusters merge, the new pin is the highest-degree merchant in the merged cluster. When removing an expired link splits a cluster, each sub-cluster gets its own pin.

For each day output "Day X" followed by the day's clusters in descending member count (ties → pin name ascending).

解法

对每一天枚举当天活跃的 link(day_added ≤ day < day_added + duration),按 link_type 建无向图,BFS 找连通块,取度最大的点作为 pin。逐日重算而非增量维护——OA 规模下 O((N + E) · D) 可接受。

from collections import defaultdict, deque

def cluster_days(batches):
    edges = []
    out = []
    for day, batch in enumerate(batches, 1):
        for u, link_type, dur, _ in batch:
            edges.append((u, link_type, day + dur, day))
        active = [e for e in edges if e[3] <= day < e[2]]
        g = defaultdict(set)
        link_groups = defaultdict(list)
        for u, lt, _, _ in active:
            link_groups[lt].append(u)
        for members in link_groups.values():
            for i in range(len(members)):
                for j in range(i + 1, len(members)):
                    g[members[i]].add(members[j])
                    g[members[j]].add(members[i])
        visited = set()
        clusters = []
        for node in g:
            if node in visited: continue
            comp = []
            dq = deque([node])
            visited.add(node)
            while dq:
                u = dq.popleft()
                comp.append(u)
                for v in g[u]:
                    if v not in visited:
                        visited.add(v); dq.append(v)
            deg = {u: len(g[u]) for u in comp}
            pin = max(comp, key=lambda x: (deg[x], -ord(str(x)[0]) if isinstance(x, str) else 0))
            clusters.append((len(comp), pin, comp))
        clusters.sort(key=lambda x: (-x[0], x[1]))
        out.append(f"Day {day}")
        out.extend(f"  cluster size={c[0]} pin={c[1]}" for c in clusters)
    return out
  • Part 1: Datacenter registry. REGISTER <name> <lat> <lon> <capacity> — validate lat ∈ [-90, 90], lon ∈ [-180, 180], capacity ≥ 0, no duplicate names. SET_HEALTHY <name> <true/false>.
  • Part 2: Distance. DISTANCE <lat1> <lon1> <lat2> <lon2> — Haversine, return integer km.
a = sin²(Δφ / 2) + cos(φ1) · cos(φ2) · sin²(Δλ / 2)
c = 2 · atan2(sqrt(a), sqrt(1 - a))
distance = 6371 · c
  • Part 3: Routing with capacity. ROUTE <lat> <lon> — route to the nearest healthy datacenter with load < capacity. Tie → name ascending. Increment chosen datacenter's load.
Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

Dataframe df with columns restaurant_id, location_code, cuisines (space-separated lowercase strings):

  1. Drop restaurants offering fewer than 3 cuisines.
  2. Strip location_code to alphanumeric characters only.
  3. For each cleaned location, count how many restaurants offer each of italian, chinese, indian, mexican (one column per cuisine).

Output sorted by location_code ascending.

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

HackerCars is building a self-driving car. Given a training dataset of speed-sign images and labels (0 = 30 km/h, 1 = 70 km/h, 2 = 120 km/h), build a PyTorch model that predicts a label for each test image and writes submissions.csv (path,label).

Schema:

FieldTypeDescription
pathstrimage path under test/
labelint0 = 30 km/h, 1 = 70 km/h, 2 = 120 km/h

Evaluation metric: accuracy.

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

Q1: Exponential distribution rate comparison

Three exponential pdf curves A, B, C plotted on the same axes. The curve with the highest peak at x = 0 corresponds to the largest rate parameter λ (since pdf(0) = λ), and decays fastest.

  • (A) A < B < C
  • (B) C < B < A
  • (C) A = B = C
  • (D) Cannot be determined.

Answer: B (C < B < A). Reading the typical OA plot: curve A peaks highest at 0 and drops fastest → largest λ; C peaks lowest and decays slowest → smallest λ.

Q2: Picking cards with replacement

Pick a card from a standard 52-card deck, replace it, pick again.

  • P1 = P(Ace then King) = (4/52) · (4/52) = 1/169.
  • P2 = P(King then Ace) = (4/52) · (4/52) = 1/169.

Answer: p1 = p2. With replacement the two draws are independent and the marginal probabilities are equal.

Q3: Skewness reduction for right-skewed data

Prepare a right-skewed dataset for linear regression. Best technique?

  • (A) Square-root transformation
  • (B) Replace outliers with the mode
  • (C) IQR outlier filter + mean normalisation
  • (D) Bivariate analysis to find correlations

Answer: A. Monotonic transforms (sqrt, log, Box-Cox) compress the right tail and reduce skewness while preserving order. Outlier replacement and bivariate analysis don't normalise the distribution.

Q4: Hypothesis testing — which statements are correct?

  • (A) p-value < α ⇒ reject H0 and conclude evidence for H1.
  • (B) p-value < α ⇒ reject H1 and accept H0.
  • (C) p-value ≥ α ⇒ accept H0.
  • (D) p-value ≥ α ⇒ fail to reject H0.

Answer: A, D. "Fail to reject H0" is not the same as "accept H0" — you simply have insufficient evidence against it.

Q5: Reducing overfitting on noisy data

The cleanest fix without inflating bias too much?

  • (A) Increase model complexity
  • (B) Shrink training set
  • (C) L1 regularization to encourage parameter sparsity
  • (D) Use plain linear regression

Answer: C. L1 (Lasso) zeroes out unimportant coefficients, reducing variance without large bias growth. (A) makes overfitting worse; (B) loses signal; (D) under-fits if the true relationship is non-linear.

Q6: Exponential distribution pmf vs pdf phrasing

The OA mislabels the exponential probability density function as a "probability mass function". The exponential distribution is continuous and has a pdf, not a pmf. Knowing this is enough to eliminate distractors that hinge on the discrete interpretation.

Answer: awareness — pdf, not pmf.

Hi there! The description you are currently reading is just 1^st part of the problem set. It is highly recommended to read ALL THE PARTS before coding as parts may build on top of each other

  • Card Range Obfuscation Part 1 (ML Eng :)
  • Card Range Obfuscation Part 2 (ML Eng :)
  • Card Range Obfuscation Part 3 (ML Eng :)
  • Card Range Obfuscation Part 4 (ML Eng :) Payment card numbers are composed of eight to nineteen digits, the leading six of which are referred to as the bank identification number (BIN). Stripe's card metadata API exposes info about different card brands within each BIN range, by returning a mapping of card intervals to brands. HOWEVER, a given BIN range may have gaps at the beginning, middle, or end of the range where no valid cards are present. This info can be used by fraudsters to test for valid credit cards within a high degree of probability. To prevent fraudsters from abusing the data gaps, we must fill in missing values by extending the returned intervals to cover the entire range!! A BIN range refers to all the 16-digit card numbers starting with a given BIN: for example, a BIN of 424242 has a range of 4242420000000000 (p.s. too many zeros, if you find anything wrong, pls lmk! Many thanks in advance :) to 4242429999999999 (p.s. too many 9s; my eyes are blind.. if you find anything wrong, pls lmk! Many thanks in advance :) An interval is a subset of a BIN range, also inclusive. In this problem, we will be taking as input as 6-digit BIN and a list of 10-digit intervals within the BIN range corresponding to brands. We will return a list of sorted intervals covering the entire BIN range (i.e. for a BIN of 424242), covering 4242420000000000 to 4242429999999999, inclusive). Input Format Your input will consist of one line containing a six-digit BIN, one line containing a positive integer N, and N lines containing intervals and their corresponding brands. The format of each interval is start, end, brand, where start and end are 10 digits following the input BIN and branch is an alphanumeric string. Example: Output Format Your output will consist of one or more lines containing the resulting intervals and their corresponding brands. The output intervals should be sorted by start Part 1 For the first set of testcases, you will be given a set of non-overlapping intervals with gaps on the lower end and/or higher end of the BIN range. You are expected to extend the lowest interval to the lower boundary of the BIN range, and the highest to the higher boundary of the BIN range. This will be sufficient to solve the first 4 test cases.

Example 1

Input:

BIN = 424242
N = 1
info = [["5000000000", "6555555555", "VISA"]]

Output:

[["4242420000000000", "4242429999999999", "VISA"]]

Explanation: Example 1: the VISA interval was extended on the lower and higher ends to cover the BIN range. Note - I double checked the input & output numbers while uploading, but since there are so many digits, I might count them wrong. If you notice anything wrong, pls feel free to lmk. I am more than happy to modify accordingly. Many thanks in advance! You da best!!

Example 2

Input:

BIN = 424242
N = 2
info = [["4000000000", "8999999999", "MASTERCARD"], ["1000000000", "3999999999", "VISA"]]

Output:

[["4242420000000000", "4242423999999999", "VISA"], ["4242424000000000", "424242429999999999", "MASTERCARD"]]

Explanation: Example 2: the VISA interval was extended on the lower end and the Mastercard interval was extended on the higher end. Note - I double checked the input & output numbers while uploading, but since there are so many digits, I might count them wrong. If you notice anything wrong, pls feel free to lmk. I am more than happy to modify accordingly. Many thanks in advance! You da best!!

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

Hi there! The description you are currently reading is just 2^nd part of the problem set. It is highly recommended to read ALL THE PARTS before coding as parts may build on top of each other

  • Card Range Obfuscation Part 1 (ML Eng :)
  • Card Range Obfuscation Part 2 (ML Eng :)
  • Card Range Obfuscation Part 3 (ML Eng :)
  • Card Range Obfuscation Part 4 (ML Eng :) Part 2 For the second set of testcases, the set of non-overlapping intervals can also contain gaps in between known intervals. In these casds, the interval on the lower end of the gap will be extended to fill the gap. This will be sufficient to solve the next 4 test cases.

Example 1

Input:

BIN = 424242
N = 2
info = [["0000000000", "3700000000", "VISA"], ["6100000000", "9999999999", "MASTERCARD"]]

Output:

[["4242420000000000", "4242426099999999", "VISA"], ["4242426100000000", "4242429999999999", "MASTERCARD"]]

Explanation: Example 1: the VISA interval was extended on the higher end to fill the gap, up to the Mastercard interval. Note - I double checked the input & output numbers while uploading, but since there are so many digits, I might count them wrong. If you notice anything wrong, pls feel free to lmk. I am more than happy to modify accordingly. Many thanks in advance! You da best!!

Example 2

Input:

BIN = 424242
N = 3
info = [["100000000", "1299999999", "VISA"], ["1900000000", "9999999999", "AMEX"], ["1500000000", "1699999999", "MASTERCARD"]]

Output:

[["4242420000000000", "4242421499999999", "VISA"], ["4242421500000000", "4242421899999999", "MASTERCARD"], ["4242421900000000", "4242429999999999", "AMEX"]]

Explanation: Example 2: the VISA interval was extended on the higher end to fill the gap up to the Mastercard interval. The Mastercard interval is extended on the higher end to fill the gap up to the Amex interval. The VISA interval is extended on the lwoer end following the requirements in Part 1 Note - I double checked the input & output numbers while uploading, but since there are so many digits, I might count them wrong. If you notice anything wrong, pls feel free to lmk. I am more than happy to modify accordingly. Many thanks in advance! You da best!!

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

Hi there! The description you are currently reading is just 2^nd part of the problem set. It is highly recommended to read ALL THE PARTS before coding as parts may build on top of each other

  • Card Range Obfuscation Part 1 (ML Eng :)
  • Card Range Obfuscation Part 2 (ML Eng :)
  • Card Range Obfuscation Part 3 (ML Eng :)
  • Card Range Obfuscation Part 4 (ML Eng :) Part 3 For the third set of testcasds, the input may contain intervals that are proper subsets of other intervals. When extending an interval to cover a gap, you should only extend the covering interval. This will be sufficient to solve the next 2 testcases. Unfortunately, this is all the information we currently have about Part 3. To ensure successful uploading, the example input and output provided are just placeholders. I hope they still help you grasp the overall problem set. Thank you so much for your understanding and support!

Example 1

Input:

BIN = 424242
N = 2
info = [["0000000000", "5999999999", "VISA"]]

Output:

[["4242420000000000", "4242429999999999", "VISA"]]

Explanation: Example 1: the first VISA interval and second CB interval are extended (this statement originates from Part 3) Input & output are just placeholders :)

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

Hi there! The description you are currently reading is just 2^nd part of the problem set. It is highly recommended to read ALL THE PARTS before coding as parts may build on top of each other

  • Card Range Obfuscation Part 1 (ML Eng :)
  • Card Range Obfuscation Part 2 (ML Eng :)
  • Card Range Obfuscation Part 3 (ML Eng :)
  • Card Range Obfuscation Part 4 (ML Eng :) Part 4

Example 1

Input:

BIN = 424242
N = 2
info = [["0000000000", "5999999999", "VISA"], ["6000000000", "9999999999", "VISA"], ]

Output:

[["4242420000000000", "4242429999999999", "VISA"]]

Explanation: Example 1: the two adjacent VISA intervals were merged Note - I double checked the input & output numbers while uploading, but since there are so many digits, I might count them wrong. If you notice anything wrong, pls feel free to lmk. I am more than happy to modify accordingly. Many thanks in advance! You da best!!

Example 2

Input:

BIN = 424242
N = 3
info = [["1000000000", "3999999999", "VISA"], ["5000000000", "6999999999", "VISA"], ["8000000000", "9999999999", "MASTERCARD"],]

Output:

[["4242420000000000", "4242427999999999", "VISA"],["4242428000000000", "4242429999999999", "MASTERCARD"]]

Explanation: Example 2: the VISA intervals were extended to fill the gaps, then merged. Note - I double checked the input & output numbers while uploading, but since there are so many digits, I might count them wrong. If you notice anything wrong, pls feel free to lmk. I am more than happy to modify accordingly. Many thanks in advance! You da best!!

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

You are building a billing component for a chat-based AI platform that charges users based on token usage. Each chat session generates a record containing: user_id,input_tokens,output_tokens,plan You are given a list of chat session records for a single month. A user may appear multiple times in the list, representing multiple chat sessions during the month. You will implement the function calculateMonthlyBilling that takes the list of chat sessions, and returns a list of strings representing each user's total spend for that month, in the format user_id: $xx.xx. Requirement 1: Pay as you go pricing (test cases 0–4) Pay-as-you-go pricing (plan: "payg"): Input tokens are billed at $0.03 per 100 tokens Output tokens are billed at $0.04 per 100 tokens Notes: Token counts will always be non-negative integers Billing is done in blocks of 100 tokens. Any partial block is not charged. For example, 0–99 tokens → 0 blocks billed, 100–199 tokens → 1 block billed, 200–299 tokens → 2 blocks billed, etc. A user that has no full blocks (i.e. uses less than 100 tokens per session) should still be in the output array with $0.00 as their spend The output array should be ordered alphabetically by user_id Requirement 2: Fixed pricing (test cases 5–9) Extend the function to calculate spend for the fixed monthly plan (plan: "fixed"): Flat fee: $15.00 per month Includes: 40,000 input tokens and 20,000 output tokens Any usage above the included tokens ("overage") is charged at the pay-as-you-go rates Requirement 3: Plan switching (test cases 10–13) Users are able to switch plans during a billing cycle. If a user switches plans, prorate the fixed plan fee and allowances by number of sessions. For example, if the user had 2 sessions on "pay-as-you-go", and 2 sessions on "fixed" (4 sessions total), their $15 fee and allowances for the fixed sessions would be reduced by 50%. Note: token usage blocks should be calculated per plan, and costed separately.

Example 1

Input:

sessions = ["userA,100,120,payg","userB,150,100,payg","userB,100,130,payg"]

Output:

["userA: $0.07","userB: $0.14"]

Explanation: userA: (100/100 * $0.03) + (120/100 blocks = 1 block * $0.04) = $0.03 + $0.04 = $0.07. userB session 1: (1 block input * $0.03) + (1 block output * $0.04) = $0.07. userB session 2: (1 block input * $0.03) + (1 block output * $0.04) = $0.07. userB total = $0.14.

Example 2

Input:

sessions = ["userA,100,100,payg","userB,20000,10000,fixed","userB,25000,12000,fixed"]

Output:

["userA: $0.07","userB: $17.30"]

Explanation: userA payg: $0.03 + $0.04 = $0.07. userB fixed: flat fee $15.00 + overage on input (45000 - 40000 = 5000 tokens = 50 blocks * $0.03/block... wait, rate is $0.03 per 100 tokens so 5000 * 0.03 / 100 = $1.50) + overage on output (22000 - 20000 = 2000 tokens, 2000 * 0.04 / 100 = $0.80). Total = 15.00 + 1.50 + 0.80 = $17.30.

Example 3

Input:

sessions = ["userA,100,100,payg","userA,100,100,payg","userA,20000,10000,fixed","userA,100,100,fixed","userB,100,100,payg"]

Output:

["userA: $7.71","userB: $0.07"]

Explanation: userA has 4 sessions total: 2 payg + 2 fixed. Two payg sessions: 2 * ($0.03 + $0.04) = $0.14. Fixed plan prorated to 2/4 = 50%: fee = $7.50, allowances = 20000 input + 10000 output. Fixed sessions usage: 20100 input (overage 100 = 1 block * $0.03 = $0.03) + 10100 output (overage 100 = 1 block * $0.04 = $0.04) = $0.07. Total: 0.14 + 7.50 + 0.07 = $7.71. userB: $0.07.

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

Complete the function below. The function receives the full standard input as a single string and must return the exact standard output lines for the described problem. Problem: Email Log Processing (Grouping + Rule-based Sorting) You are given a list of email event logs logs. Each log is a single line string in the format: <timestamp> <sender_email> <receiver_email> <subject>

  • timestamp: a non-negative integer (seconds since epoch)
  • sender_email, receiver_email: strings without spaces
  • subject: the remainder of the line starting from the 4th token; may contain spaces (may be empty)

Group logs by sender_email, sort each group, and print the result.

Rules Within the same sender, sort logs by timestamp ascending; tie-break by receiver_email lexicographic ascending; then by subject lexicographic ascending. Output sender groups in lexicographic order of sender_email.

Input Line 1: integer n, number of logs. Next n lines: one log per line.

Output For each sender, print: sender: <sender_email> Then print each sorted log line as: <timestamp> <receiver_email> <subject> Note: sender_email is not printed on the log lines. Constraints 1 ≤ n ≤ 2 * 10⁵ 0 ≤ timestamp ≤ 10⁹ Each line length ≤ 300 Example Input 5 100 alice@a.com bob@b.com hello 90 alice@a.com carl@c.com meeting notes 90 dan@d.com e@e.com hi 90 alice@a.com bob@b.com a-subject 100 dan@d.com a@a.com ping Output sender: alice@a.com 90 bob@b.com a-subject 90 carl@c.com meeting notes 100 bob@b.com hello sender: dan@d.com 90 e@e.com hi 100 a@a.com ping Function Description Complete solveEmailLogGroupingAndSorting. It has one parameter, String input, containing the full stdin payload. Return the stdout payload as an array of lines, without trailing newline characters.

Constraints

Use the limits and requirements stated in the prompt.

Example 1

Input:

input = "1\n0 a@a.com b@b.com hi"

Output:

["sender: a@a.com", "0 b@b.com hi"]

Explanation: The returned string must match the expected standard output for the sample input.

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

Hi there! The description you are currently reading is just 2^nd part of the problem set. It is highly recommended to read ALL THE PARTS before coding as parts may build on top of each other

  • For All Intents And Purposes Part 1 - Initilizing the System
  • For All Intents And Purposes Part 2 - Change Is Good!
  • For All Intents And Purposes Part 3 - Accepting Failure
  • For All Intents And Purposes Part 4 - Timing Matters The initial version of our system looks good ! But it turns out merchants also need to be able to update the amount of initialized Payment Intents. This happen if a customer begins to check out but then decides to change the items in their shopping cart and thus the amount of the payment. Let's add that the our system ! Your system should support an additional command for updaing a Payment Intent. UPDATE <payment_intent_id> <new amount> Update the monetary amount of an existing Payment Intent in the REQUIRES_ACTION state. This does not transition the state of the Payment Intent. If no Payment Intent with the given identifier exists, or if the Payment Intent is not in the REQUIRES_ACTION state, or if the new amount is negative, this mommand should do nothing.

Example 1

Input:

commands = ["INIT m1 0", "CREATE p1 m1 50", "UPDATE p1 100", "ATTEMPT p1", "SUCCEED p1"]

Output:

["m1 100"]

Explanation: While the Payment Intent p1 was initially created with an amount of 50, this was then updated to 100 before being attempted then succeeded. Therefore, merchant m1 has a balance of 100 after all commands have been processed.

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

Hi there! The description you are currently reading is just 3^rd part of the problem set. It is highly recommended to read ALL THE PARTS before coding as parts may build on top of each other

  • For All Intents And Purposes Part 1 - Initilizing the System
  • For All Intents And Purposes Part 2 - Change Is Good!
  • For All Intents And Purposes Part 3 - Accepting Failure
  • For All Intents And Purposes Part 4 - Timing Matters The rest of the team is thrilled with our progress building Stripe's new Payment Intent processor, but they pointed out a few cases we should handle before releasing the system to the public First, payments don't alway succeed and can fail for a variety of reasons like a card network declining a transaction or a bank account not having sufficient funds to be debited. Second, even after payments have succeeded, customers need to be able to request refunds from merchant. Let's update our implementation to handle two new commands: FAIL and REFUND . FAIL <payment_intent_id> Fails a payment intent in the PROCESSING state, transitioning it from PROCESSING to REQUIRES_ACTION. This occurs when the customer's payment was declined. If no Payment Intent with the given identifier exists, or if the Payment Intent is not in the PROCESSING state, this command should do nothing. REFUND <payment_intent_id> Processes a refund for a previously successful payment intent in the COMPLETED state. This should decrement the merchant's balance by the amount of the Payment Intent in order to return the refund to the customer If no Payment Intent with the given identifier exists, or if the Payment Intent is not in the COMPLETED state, or if the Payment Intent has already been refunded, this command should do nothing.

Example 1

Input:

commands = ["INIT m1 0", "CREATE p1 m1 50", "ATTEMPT p1", "FAIL p1", "ATTEMPT p1", "SUCCEED p1", "CREATE p2 m1 100", "ATTEMPT p2", "SUCCEED p2", "REFUND p2"]

Output:

["m1 50"]

Explanation: The Payment Intent p1 was created with an amount of 50, then attempted, then failed which transitioned it back to the REQUIRES_ACTION, then attempted, then succeeded. At that point, m1's balance was 50. The Payment Intent p2 was created with a amount of 100, then attempted, then succeeded. At that point, m1's balance was 150. Then p2 was refunded, so m1's balance after executing all commands is 50 :)

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

Hi there! The description you are currently reading is just 4^th part of the problem set. It is highly recommended to read ALL THE 4 PARTS before coding as parts may build on top of each other

  • For All Intents And Purposes Part 1 - Initilizing the System
  • For All Intents And Purposes Part 2 - Change Is Good!
  • For All Intents And Purposes Part 3 - Accepting Failure
  • For All Intents And Purposes Part 4 - Timing Matters Last month, we received the new Payment Intent system you built , and merchants have been LOVING how simple it makes accepting payments. Congratulations ! However, numerous merchants have requested that we augment our refund functionality by letting merchants specify a refund timeout policy: the amount of time after a payment succeeds that refunds are permitted. For example, one merchant, LlmaCorp, only wants to accept refunds within 15 days of a payment succeeding. Being able to return a llama afte 15 days would be absurd after all. Let's add this functionality to our system, which means we will need to change the format of our commands to handle timing . Timestamps All commands will now have an integer timestamp in front. For example, intead of SUCCEED , you will now receiveSUCCEED You can assume that the timestamps will always be integers (representing a unit of time) and that the timestamps of the list of commands will be strictly increasing Merchant Refund Timeout Limit The INIT command that initializes a merchant will now have an optional third argument specifying the merchant's refund timeout limit. The new specification is - <timestamp> INIT <merchant_id> <starting_balance> <refund_time_out_limit> If a merchant has a refund_timeout_limit of n, and succeeds a Payment Intent (with the SUCCEED command) at timestamp t, then the timestamp of a REFUND command must be no greater than t + n, otherwise the refund should no succeed. iF A refund_timeout_limit is not specified during merchant initialization, there is no refund time limit, a a refund should succeed regardless how much time has passed since Payment Intent confirmation. A reund_timeout_limit of 0 means no refunds should be accepted ever, and a negative refund_timeout_limit should be ignore (meaning all refunds should be accepted)

Example 1

Input:

commands = ["1 INIT m1 0 5", "2 CREATE p1 m1 100", "3 CREATE p2 m1 50", "4 ATTEMPT p1", "5 ATTEMPT p2", "8 SUCCEED p1", "10 SUCCEED p2", "11 REFUND p1", "16 REFUND p2"]

Output:

["m1 50"]

Explanation: p1 was succeeded at time 8 and refunded at time 11, within merchant m1's refund timeout limit of 5, so the refund succeeded. p2 was succeeded at time 10 and refunded at time 16, and 16 − 10 = 6 > 5, exceeding m1's timeout limit, so that refund failed. p1's refund deducts 100 from balance 100 → 0; p2 untouched at +50. Final balance: m1 → 50.

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

Hi there! The description you are currently reading is just 1^st part of the problem set. It is highly recommended to read ALL THE PARTS before coding as parts may build on top of each other

  • For All Intents And Purposes Part 1 - Initilizing the System
  • For All Intents And Purposes Part 2 - Change Is Good!
  • For All Intents And Purposes Part 3 - Accepting Failure
  • For All Intents And Purposes Part 4 - Timing Matters Background Stripe processes billions of dollars of payments to businesses every day through dozens of different payment methods like cards, bank debits, and even papaer cheques. We don't want merchants (the businesses who use Stripe to accept peyments) to have to worry about the details for each specific payment method. For example, for many payment methods, payments are not completed instantly and can take a few days to process and be confirmed or fail, while others are processed much more quickly. Stripe abstracts this payment flow with a simple state machine object called a Payment Intent. Today, imagine you are an engineer working at Stripe in its early days. You will implement a system that handles the creation and management of these Payment Intens, helping merchants easily setup and accept payments from customers. Please read all instructions for each part before you begin coding for that part. What is a Payment Intent? A Payment Intent tracks a payment through its flow from initilization to processing to confirmation. We model this flow as a state machine: an abstract object that can exist in one of a number of states and transition between states. A Payment Intent stores information like the merchant receiving the peyment and the monetary amount. It also should keep track of its state, which can be one of three values REQUIRES_ACTION The initial state of a Payment Intent upon creation. Can transition to PROCESSING. PROCESSING The customer has attempted to pay but the attempt has not yet succeeded or failed. Can transition to either REQUIRES_ACTION or COMPLETED COMPLETED The attempt to pay succeeded and the Payment Intent amount was added to the merchant's balance. You Task You will implement a function that executes a chronologically ordered list of commands to create and manage Payment Intents for different merchants and then returns the account balances for each merchant after executing all commands. Input You will receive a chronologically ordered list of commands in the form ['INIT m1 0', 'CREATE p1 m1 100'] where each command is a single string. You will also receive the part number, corresponding to the pairs in the problem description. The commands you need to support are decribed below. Output A list of merchant balances in the form ['m1 100', 'm2 200'] representing the balance for each merchant after executing all commands. The list should be sorted by merchant ID in ascending alphabetical order. Part 1: Good Intentions To build the initial version of our system, we will support a few basic commands for initializing a merchant, creating a Payment Intent, attempting a Payment Intent, and succeeding a Payment Intent. For this part, your system should handle the following commands - INIT <merchant_id> <starting_balance> Initializes a merchant with a unique identifier string and starting balance (the amount of money in their account). If a merchant with the given identifier has already been created, this command should do nothing. CREATE <payment_init_id> <merchant_id> <amount> Creates a Payment Intent for a merchant with a given amount. After creation, the state of the Payment Intent should be REQUIRES_ACTION. If a Payment Intent with the given identifier already exists, or if a merchant with the given identifier does not exist, or if the amount is negative, this command should do nothing. ATTEMPT <payment_init_id> Transitions a Payment Intent with a given identifier from the REQUIRES_ACTION state to the PROCESSING state. If no Payment Intent with the given identifier exists, or if the state of the Payment Intent is not REQUIRES_ACTION, this command should do nothing. SUCCEED <payment_init_id> Transitions a Payment Intent with a given identifier from the PROCESSING state to the COMPLETED state If no Payment Intent with the given identifier exists, or if the state of the Payment Intent is not PROCESSING, this command should do nothing.

Example 1

Input:

commands = ["INIT m1 0", "INIT m2 10", "CREATE p1 m1 50", "ATTEMPT p1", "SUCCEED p1", "SUCCEED p1", "CREATE p2 m2 100", "ATTEMPT p2"]

Output:

["m1 50", "m2 10"]

Explanation: Let's look at what happened for each command

  • INIT m1 0 initializes merchant m1 with a starting balance of 0
  • INIT m2 10 initializes merchant m2 with a starting balance of 10
  • Create p1 m1 50 creates a Payment Intent p1 for merchangt m1 with an amount of 50 and initial state of REQUIRES_ACTION initializes merchant m2 with a starting balance of 10
  • ATTEMPT p1 transitions p1 from REQUIRES_ACTION to PROCESSING
  • SUCCEED p2 transitions p2 from PROCESSING to COMPLETED and increments merchant m1's balance by 50
  • CREATE p2 m2 100 creates a Payment Intent p2 for merchant m2 with an amount of 100 and initial state of REQUIRES_ACTION
  • ATTEMPT p2 transitions p2 from REQUIRES_ACTION to PROCESSING Because only p1 was successfully completed, at the end of executing all of the commands, m1 should have a balance of 50 and m2 should have a balance of 10 :D
Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

You are given a datetime range [startDate, endDate] and a weekly recurring working-hours configuration. Generate every available 30-minute slot that is fully contained in the range and also lies inside one of the working-hour windows for the corresponding weekday. Each slot is represented as a string "start,end", where the start and end timestamps are separated by a comma. The first and last days must be validated using the exact time boundaries: a slot is valid only when slotStart ≥ startDate and slotEnd ≤ endDate. Function Description Complete the function generateAvailableTimeSlots in the editor below. generateAvailableTimeSlots has the following parameters:

  • String startDate: inclusive lower datetime bound in YYYY-MM-DD HH:MM format
  • String endDate: inclusive upper datetime bound in YYYY-MM-DD HH:MM format
  • String[][] workingHours: each row is [weekday, windowStart, windowEnd], where weekday is 0 for Monday through 6 for Sunday Returns String[]: all valid 30-minute slots in chronological order.

Constraints

  • workingHours repeats weekly.
  • Only full 30-minute slots are emitted.
  • Output must be sorted chronologically.

Example 1

Input:

startDate = "2026-01-05 09:10"
endDate = "2026-01-05 10:40"
workingHours = [["0", "09:00", "12:00"]]

Output:

["2026-01-05 09:30,2026-01-05 10:00", "2026-01-05 10:00,2026-01-05 10:30"]

Explanation: The 09:00-09:30 slot starts before the allowed range, and the 10:30-11:00 slot ends after the allowed range. The two middle 30-minute slots are fully contained.

Example 2

Input:

startDate = "2026-01-06 13:00"
endDate = "2026-01-06 14:00"
workingHours = [["1", "12:30", "14:30"]]

Output:

["2026-01-06 13:00,2026-01-06 13:30", "2026-01-06 13:30,2026-01-06 14:00"]

Explanation: Only the two full 30-minute slots inside both the Tuesday working window and the requested datetime range are returned.

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

The system simulates a transaction intent management tool to handle the process from initialization to completion and calculate the final balances of merchants' accounts. Transaction states include: PENDING: The transaction is created and awaiting processing. IN_PROGRESS: The transaction is being processed. DONE: The transaction is completed, and the balance is updated. Core Features:

  • START <account_id> <initial_balance> <refund_limit> (optional): Initializes a merchant account with an initial balance and an optional refund limit.
  • NEW <transaction_id> <account_id> <amount>: Creates a transaction intent for the specified account with the given amount in the PENDING state.
  • PROCESS <transaction_id>: Moves a transaction from PENDING to IN_PROGRESS.
  • COMPLETE <transaction_id>: Moves a transaction from IN_PROGRESS to DONE and adds the amount to the merchant's balance.

Extended Features:

  • MODIFY <transaction_id> <new_amount>: Updates the amount for a PENDING transaction intent.
  • CANCEL <transaction_id>: Reverts a transaction from IN_PROGRESS to PENDING.
  • RETURN <transaction_id>: Processes a refund for a DONE transaction and deducts the amount from the account's balance.

Time-Limited Refunds: Each command includes a <time> marker indicating the timestamp. Merchants can set a refund time limit; transactions can only be refunded within this limit. If no limit is set, refunds are allowed indefinitely. A limit of 0 means no refunds are allowed. Task Objective: Process a list of commands to manage transaction intents and output the final balances of all accounts. Input Format: A time-ordered list of commands. Output Format: A list of account balances in ascending order by account ID.

Example 1

Input:

commands = ["START account1 0", "NEW txn1 account1 50", "PROCESS txn1", "COMPLETE txn1"]

Output:

["account1 50"]

Explanation: The commands are processed as follows:

  • START account1 0: Initializes account1 with a balance of 0.
  • NEW txn1 account1 50: Creates a new transaction intent txn1 for account1 with an amount of 50 in PENDING state.
  • PROCESS txn1: Moves txn1 to IN_PROGRESS state.
  • COMPLETE txn1: Moves txn1 to DONE state and adds the amount to account1's balance, resulting in a final balance of 50. The final balance for account1 is 50.

Example 2

Input:

commands = ["START account1 0", "NEW txn1 account1 50", "PROCESS txn1", "CANCEL txn1", "PROCESS txn1", "COMPLETE txn1", "RETURN txn1"]

Output:

["account1 0"]

Explanation: The commands are processed as follows:

  • START account1 0: Initializes account1 with a balance of 0.
  • NEW txn1 account1 50: Creates a new transaction intent txn1 for account1 with an amount of 50 in PENDING state.
  • PROCESS txn1: Moves txn1 to IN_PROGRESS state.
  • CANCEL txn1: Reverts txn1 to PENDING state.
  • PROCESS txn1: Moves txn1 back to IN_PROGRESS state.
  • COMPLETE txn1: Moves txn1 to DONE state and adds the amount to account1's balance, resulting in a balance of 50.
  • RETURN txn1: Processes a refund for txn1 and deducts the amount from account1's balance, resulting in a final balance of 0. The final balance for account1 is 0.

Example 3

Input:

commands = ["1 START account1 0 5", "2 NEW txn1 account1 100", "8 COMPLETE txn1", "11 RETURN txn1", "16 RETURN txn1"]

Output:

["account1 100"]

Explanation: The commands are processed as follows:

  • 1 START account1 0 5: Initializes account1 with a balance of 0 and a refund limit of 5.
  • 2 NEW txn1 account1 100: Creates a new transaction intent txn1 for account1 with an amount of 100 in PENDING state.
  • 8 COMPLETE txn1: Moves txn1 to DONE state and adds the amount to account1's balance, resulting in a balance of 100.
  • 11 RETURN txn1: Processes a refund for txn1 within the refund limit and deducts the amount from account1's balance, resulting in a balance of 0.
  • 16 RETURN txn1: The refund is not processed because it is outside the refund limit, so the balance remains 100. The final balance for account1 is 100.
Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁

Complete the function below. The function receives the full standard input as a single string and returns the exact standard output lines for a request-routing command processor. You are building a request routing system for datacenters. The system supports commands that register datacenters, update their health, compute geographic distance, and route user requests to the nearest available healthy datacenter. Each datacenter has a unique name, latitude, longitude, capacity, health status, and current load. A newly registered datacenter is healthy and has load 0. Supported commands:

  • REGISTER name latitude longitude capacity: add a datacenter. Return OK if the name is new, latitude is in [-90, 90], longitude is in [-180, 180], and capacity is greater than 0; otherwise return ERROR.
  • SET_HEALTHY name value: set health to true or false. Return OK for an existing datacenter and valid boolean value; otherwise return ERROR.
  • DISTANCE lat1 lon1 lat2 lon2: compute the great-circle distance in kilometers using Earth radius 6371 and the Haversine formula. Return the nearest integer distance. Return ERROR for invalid coordinates.
  • ROUTE latitude longitude: among healthy datacenters, sort by distance to the user ascending, breaking ties by datacenter name. Choose the first datacenter whose current load is less than capacity, increment its load by 1, and output name distance candidates. If no healthy datacenter has capacity left, output None candidates. candidates is the comma-separated ordered list of healthy datacenter names considered by the router. Process commands in order and return one output line per command. Function Description Complete solveRequestRoutingSystem. It has one parameter, String input, containing newline-separated commands. Return the stdout payload as an array of lines, without trailing newline characters.

Constraints

Coordinate validation follows the exact bounds stated in the prompt. Capacity must be a positive integer. Distances use Earth radius 6371 km and are rounded to the nearest integer.

Example 1

Input:

input = "REGISTER us-west 38 -122 100\nREGISTER us-east 41 -74 150\nREGISTER us-west 50 -100 50\nREGISTER invalid-node 91 0 100\nREGISTER invalid-cap 0 0 0\nSET_HEALTHY us-east false\nSET_HEALTHY fake-node true"

Output:

["OK","OK","ERROR","ERROR","ERROR","OK","ERROR"]

Explanation: The duplicate datacenter name, invalid latitude, invalid capacity, and unknown datacenter update are rejected.

Example 2

Input:

input = "DISTANCE 38 -122 41 -74\nDISTANCE 0 0 0 0\nDISTANCE 91 0 0 0"

Output:

["4080","0","ERROR"]

Explanation: The first distance is rounded to the nearest kilometer; the last command has an invalid latitude.

Example 3

Input:

input = "REGISTER node-A 0 0 1\nREGISTER node-B 0 0 1\nREGISTER node-C 10 10 100\nSET_HEALTHY node-C false\nROUTE 0 0\nROUTE 0 0\nROUTE 0 0"

Output:

["OK","OK","OK","OK","node-A 0 node-A,node-B","node-B 0 node-A,node-B","None node-A,node-B"]

Explanation: The unhealthy node-C is not considered. The two healthy nodes are selected once each, then both are at capacity.

Pro解法 · 三语代码 · 复杂度分析
边界讨论 + 面试官追问 · $98 / 一年解锁
Pro 会员

解锁全部 17 道题的解法

题面你已经看到了 — 解法 + 三语代码 + 复杂度推导 + 边界讨论, Pro 解锁.

Pro 解锁全部
  • 📚1000+ 道真实北美 OA, Python / Java / C++ 三语题解
  • 📊个人 dashboard + 进度可视化 + 14 天活跃图
  • 📝题目笔记跨设备同步 + 个人复盘库
  • 🔓随时取消下次续费, Stripe Customer Portal 自助管理
$12/月($98/年, 一次付清省 32%)

≈ 北美 SWE 工资 10 分钟 · LeetCode Premium $35/月 的 23%