登录
OAmaster

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. User Journey Paths (Action Log Trie Summary) You are given action logs emitted by a platform. Each log entry is a tuple: (user_id, time, action). Build a path tree (Trie-like summary) of users’ journeys: For each user, sort their logs by time ascending to obtain that user’s action sequence. Insert each user’s sequence into a tree. Each node represents an action; a path from the root represents an action-prefix. Each node stores a count = the number of distinct users whose journey reached that node via that prefix. Input List[Tuple[int, int, str]] log entries (user_id, time, action). Output Return an indented string representation of the tree: Do not print the root. Each line: ACTION (count). Children are indented by two spaces and prefixed with -> . For deterministic output, print siblings in lexicographic order by action. Notes / Edge cases Logs can be unordered: group by user and sort by time. Each user contributes +1 to every prefix node along their path. Repeated actions are distinct steps (e.g., A -> B -> B is valid; the second B is a child of the first B). Empty input ⇒ empty output string. Single user / single action ⇒ single node. Example Input logs: 100 1000 A 300 1150 A 200 1200 B 100 1200 B 100 1300 C 200 1400 A 300 1500 B 300 1550 B 100 1560 D Per-user sequences: user 100: A -> B -> C -> D user 200: B -> A user 300: A -> B -> B Expected output: A (2) -> B (2) -> B (1) -> C (1) -> D (1) B (1) -> A (1) Tests Use the 5 test cases described in the prompt (main example, empty, single action, identical paths, out-of-order logs). Example Input 100 1000 A 300 1150 A 200 1200 B 100 1200 B 100 1300 C 200 1400 A 300 1500 B 300 1550 B 100 1560 D Output A (2) -> B (2) -> B (1) -> C (1) -> D (1) B (1) -> A (1) Function Description Complete solveUserJourneyPaths. 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 = "100 1000 A\n300 1150 A\n200 1200 B\n100 1200 B\n100 1300 C\n200 1400 A\n300 1500 B\n300 1550 B\n100 1560 D"

Output:

["A (2)", " -> B (2)", " -> B (1)", " -> C (1)", " -> D (1)", "B (1)", " -> A (1)"]

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

解法

解析日志、按 user 分组、各组按 time 升序得到 action 序列。把每条序列插入到一棵 Trie:每访问/创建一个节点 count += 1。DFS 输出(按 action 字典序)每个节点:根节点不打印,子节点行用 " -> " 前缀,并按深度缩进。每深一层多两个空格。时间 O(总 action 数),空间同。

from collections import defaultdict
from typing import List

def solve_user_journey_paths(input: str) -> List[str]:
    if not input or not input.strip():
        return []
    logs = []
    for line in input.split("\n"):
        if not line.strip():
            continue
        parts = line.split()
        uid, t, action = int(parts[0]), int(parts[1]), parts[2]
        logs.append((uid, t, action))
    by_user: dict = defaultdict(list)
    for uid, t, a in logs:
        by_user[uid].append((t, a))
    # Trie node: {"count": int, "children": {action: node}}
    root = {"count": 0, "children": {}}
    for uid, seq in by_user.items():
        seq.sort(key=lambda x: x[0])
        node = root
        for _, a in seq:
            ch = node["children"]
            if a not in ch:
                ch[a] = {"count": 0, "children": {}}
            ch[a]["count"] += 1
            node = ch[a]

    out: List[str] = []
    def dfs(node, depth: int):
        for action in sorted(node["children"]):
            child = node["children"][action]
            indent = " " * (2 * depth)
            prefix = "-> " if depth > 0 else ""
            out.append(f"{indent}{prefix}{action} ({child['count']})")
            dfs(child, depth + 1)
    dfs(root, 0)
    return out
import java.util.*;

class Solution {
    static class Node { int count; TreeMap<String, Node> children = new TreeMap<>(); }
    public List<String> solveUserJourneyPaths(String input) {
        List<String> out = new ArrayList<>();
        if (input == null || input.trim().isEmpty()) return out;
        Map<Integer, List<int[]>> byUserTime = new HashMap<>();
        Map<Integer, List<String>> byUserAct = new HashMap<>();
        for (String line : input.split("\n")) {
            if (line.trim().isEmpty()) continue;
            String[] p = line.trim().split("\\s+");
            int uid = Integer.parseInt(p[0]), t = Integer.parseInt(p[1]);
            byUserTime.computeIfAbsent(uid, k -> new ArrayList<>()).add(new int[]{t, byUserTime.getOrDefault(uid, new ArrayList<>()).size()});
            byUserAct.computeIfAbsent(uid, k -> new ArrayList<>()).add(p[2]);
        }
        Node root = new Node();
        for (var e : byUserTime.entrySet()) {
            int uid = e.getKey();
            List<int[]> times = e.getValue();
            List<String> acts = byUserAct.get(uid);
            Integer[] idx = new Integer[times.size()];
            for (int i = 0; i < idx.length; i++) idx[i] = i;
            Arrays.sort(idx, (a, b) -> Integer.compare(times.get(a)[0], times.get(b)[0]));
            Node node = root;
            for (int i : idx) {
                String a = acts.get(i);
                node = node.children.computeIfAbsent(a, k -> new Node());
                node.count++;
            }
        }
        dfs(root, 0, out);
        return out;
    }
    private void dfs(Node node, int depth, List<String> out) {
        for (var e : node.children.entrySet()) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < depth * 2; i++) sb.append(' ');
            if (depth > 0) sb.append("-> ");
            sb.append(e.getKey()).append(" (").append(e.getValue().count).append(")");
            out.add(sb.toString());
            dfs(e.getValue(), depth + 1, out);
        }
    }
}
#include <bits/stdc++.h>
using namespace std;

class Solution {
    struct Node { int count = 0; map<string, Node*> children; };
public:
    vector<string> solveUserJourneyPaths(string input) {
        vector<string> out;
        if (input.empty()) return out;
        map<int, vector<pair<int,string>>> byUser;
        stringstream ss(input); string line;
        while (getline(ss, line, '\n')) {
            if (line.empty()) continue;
            stringstream ls(line);
            int uid, t; string a;
            if (ls >> uid >> t >> a) byUser[uid].push_back({t, a});
        }
        Node root;
        for (auto& [uid, seq] : byUser) {
            sort(seq.begin(), seq.end());
            Node* node = &root;
            for (auto& [_t, a] : seq) {
                if (!node->children.count(a)) node->children[a] = new Node();
                node = node->children[a];
                node->count++;
            }
        }
        function<void(Node*, int)> dfs = [&](Node* n, int depth) {
            for (auto& [act, ch] : n->children) {
                string s(depth * 2, ' ');
                if (depth > 0) s += "-> ";
                s += act + " (" + to_string(ch->count) + ")";
                out.push_back(s);
                dfs(ch, depth + 1);
            }
        };
        dfs(&root, 0);
        return out;
    }
};