Analyze User Website Visit Pattern
Real-world version: Busiest Three-Screen TrailThe statement here is our own: the same inputs, outputs and technique.
An app's analytics log has one row per screen opening. Row i says that viewer viewer[i] opened screen screen[i] at clock reading moment[i]. The rows arrive in no particular order.
Put each viewer's own rows into increasing order of clock reading; when two of that viewer's rows share a reading, the one listed earlier in the input goes first. That gives every viewer a single ordered walk through the app.
A trail is a sequence of exactly three screen names. A viewer follows a trail when three rows can be picked out of their walk, at strictly increasing places in it, whose screen names spell the trail in order. The three places need not be next to each other, and the same screen name may appear more than once in a trail if the viewer opened that screen more than once. A viewer either follows a trail or does not; the number of different ways they could pick the rows makes no difference.
Return the trail followed by the greatest number of viewers, as a list of its three screen names. When several trails are followed by that many viewers, return the alphabetically smallest of them, comparing the three names in order.
Examples
Example 1
- Input
- viewer = ["ana", "ana", "ana", "bo", "bo", "bo"], moment = [5, 2, 9, 4, 1, 7], screen = ["cart", "dash", "help", "dash", "cart", "help"]
- Output
- ["cart", "dash", "help"]
Each of the two viewers follows exactly one trail, and the two trails differ, so both are followed by one viewer and the alphabetical rule settles it.
Example 2
- Input
- viewer = ["ana", "ana", "ana", "bo", "bo", "bo", "cy", "cy"], moment = [1, 2, 3, 1, 2, 3, 1, 2], screen = ["dash", "cart", "help", "dash", "cart", "help", "dash", "cart"]
- Output
- ["dash", "cart", "help"]
Two viewers walk the same three screens in the same order. The third viewer has only two rows in the log, so no trail is credited to them.
Example 3
- Input
- viewer = ["cy", "cy", "cy", "cy", "cy"], moment = [1, 2, 3, 4, 5], screen = ["feed", "feed", "cart", "feed", "cart"]
- Output
- ["cart", "feed", "cart"]
One viewer owns the whole log, so every trail they follow is followed by exactly one viewer and the alphabetically smallest of those trails is returned.
Constraints
- 3 <= viewer.length <= 50
- 1 <= viewer[i].length <= 10
- moment.length == viewer.length
- 1 <= moment[i] <= 10^9
- screen.length == viewer.length
- 1 <= screen[i].length <= 10
- viewer[i] and screen[i] consist of lowercase English letters.
- At least one viewer has three or more rows in the log.
- All the triples [viewer[i], moment[i], screen[i]] are distinct.
- Two rows of the same viewer may share a clock reading; the earlier row in the input then comes first.
The signature
The editor starts with this. It matches the parent problem's shape, so a solution that works here works on a standard judge unchanged.
def busiest_trail(viewer: list[str], moment: list[int], screen: list[str]) -> list[str]:public List<String> busiestTrail(String[] viewer, int[] moment, String[] screen)Checking your plan…
How this problem was checked
- Passed: Reference solution run against 9 test cases: 9 passed
- Passed: 3 worked examples confirmed by running the code
- Passed: 0 eight-word sequences shared with the parent problem's text
- Passed: Agrees with an independent brute-force solution on random inputs
- Passed: Test set shown to catch deliberately broken solutions
- Passed: Reviewed by a separate quality pass
- Passed: Function arity matches the parent problem's
More on the same topics
- Sort the PeopleReal-world version: Season Leaderboard From Two Parallel ListsEasy
- Find Resultant Array After Removing AnagramsReal-world version: Clearing Rearranged Labels Off the ShelfEasy
- Group AnagramsReal-world version: Bin Label FamiliesMedium
- Accounts MergeReal-world version: Merge Crew Badge RecordsMedium