The "Analyze User Website Visit Pattern" problem asks us to analyze a list of website visits by users and determine the most commonly visited sequence of three websites (a "3-sequence") among all users.
Each visit is represented by three lists: username
, timestamp
, and website
. Each index i
in these lists represents a single visit: username[i]
visited website[i]
at timestamp[i]
.
The task is to:
To solve this problem, the first thought is to brute-force all possible 3-sequences for every user, count their occurrences, and then pick the most common one. However, this could be inefficient if users have many visits.
We need to:
Let's break down the solution step by step:
Sample Input:
username = ["joe","joe","joe","james","james","james","james","mary","mary","mary"]
timestamp = [1,2,3,4,5,6,7,8,9,10]
website = ["home","about","career","home","cart","maps","home","home","about","career"]
Step-by-step:
["home","about","career"]
Brute-force Approach:
n
visits, generate all possible ordered 3-sequences: O(n^3) per user.The key to solving the "Analyze User Website Visit Pattern" problem is to:
from collections import defaultdict, Counter
from itertools import combinations
class Solution:
def mostVisitedPattern(self, username, timestamp, website):
# Step 1: Combine and sort visits by timestamp
visits = sorted(zip(timestamp, username, website))
user_webs = defaultdict(list)
for t, u, w in visits:
user_webs[u].append(w)
# Step 2: Generate unique 3-sequences per user
seq_users = defaultdict(set)
for user, webs in user_webs.items():
# All unique 3-sequences for this user
seqs = set(combinations(webs, 3))
for seq in seqs:
seq_users[seq].add(user)
# Step 3: Count and find the most common sequence
max_count = 0
res = tuple()
for seq, users in seq_users.items():
if len(users) > max_count or (len(users) == max_count and seq < res):
max_count = len(users)
res = seq
return list(res)
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
class Solution {
public:
vector<string> mostVisitedPattern(vector<string>& username, vector<int>& timestamp, vector<string>& website) {
vector<tuple<int,string,string>> visits;
int n = username.size();
for (int i = 0; i < n; ++i) {
visits.push_back({timestamp[i], username[i], website[i]});
}
sort(visits.begin(), visits.end());
map<string, vector<string>> userWebs;
for (auto& v : visits) {
userWebs[get<1>(v)].push_back(get<2>(v));
}
map<vector<string>, set<string>> seqUsers;
for (auto& uw : userWebs) {
string user = uw.first;
vector<string>& webs = uw.second;
int m = webs.size();
set<vector<string>> seqs;
for (int i = 0; i < m; ++i)
for (int j = i+1; j < m; ++j)
for (int k = j+1; k < m; ++k)
seqs.insert({webs[i], webs[j], webs[k]});
for (auto& seq : seqs) {
seqUsers[seq].insert(user);
}
}
int maxCount = 0;
vector<string> res;
for (auto& su : seqUsers) {
if ((int)su.second.size() > maxCount ||
((int)su.second.size() == maxCount && su.first < res)) {
maxCount = su.second.size();
res = su.first;
}
}
return res;
}
};
import java.util.*;
class Solution {
public List<String> mostVisitedPattern(String[] username, int[] timestamp, String[] website) {
int n = username.length;
List<Visit> visits = new ArrayList<>();
for (int i = 0; i < n; ++i) {
visits.add(new Visit(timestamp[i], username[i], website[i]));
}
Collections.sort(visits, (a, b) -> Integer.compare(a.time, b.time));
Map<String, List<String>> userWebs = new HashMap<>();
for (Visit v : visits) {
userWebs.computeIfAbsent(v.user, k -> new ArrayList<>()).add(v.web);
}
Map<String, Set<String>> seqUsers = new HashMap<>();
for (String user : userWebs.keySet()) {
List<String> webs = userWebs.get(user);
int m = webs.size();
Set<String> seqs = new HashSet<>();
for (int i = 0; i < m; ++i)
for (int j = i+1; j < m; ++j)
for (int k = j+1; k < m; ++k)
seqs.add(webs.get(i) + "|" + webs.get(j) + "|" + webs.get(k));
for (String seq : seqs) {
seqUsers.computeIfAbsent(seq, x -> new HashSet<>()).add(user);
}
}
int maxCount = 0;
String res = "";
for (String seq : seqUsers.keySet()) {
int size = seqUsers.get(seq).size();
if (size > maxCount || (size == maxCount && seq.compareTo(res) < 0)) {
maxCount = size;
res = seq;
}
}
return Arrays.asList(res.split("\\|"));
}
static class Visit {
int time;
String user;
String web;
Visit(int t, String u, String w) {
time = t; user = u; web = w;
}
}
}
/**
* @param {string[]} username
* @param {number[]} timestamp
* @param {string[]} website
* @return {string[]}
*/
var mostVisitedPattern = function(username, timestamp, website) {
// Step 1: Combine and sort visits by timestamp
let visits = [];
for (let i = 0; i < username.length; ++i) {
visits.push([timestamp[i], username[i], website[i]]);
}
visits.sort((a, b) => a[0] - b[0]);
let userWebs = {};
for (let [t, u, w] of visits) {
if (!userWebs[u]) userWebs[u] = [];
userWebs[u].push(w);
}
// Step 2: Generate unique 3-sequences per user
let seqUsers = {};
for (let user in userWebs) {
let webs = userWebs[user];
let m = webs.length;
let seqs = new Set();
for (let i = 0; i < m; ++i)
for (let j = i+1; j < m; ++j)
for (let k = j+1; k < m; ++k)
seqs.add([webs[i], webs[j], webs[k]].join('|'));
for (let seq of seqs) {
if (!seqUsers[seq]) seqUsers[seq] = new Set();
seqUsers[seq].add(user);
}
}
// Step 3: Count and find the most common sequence
let maxCount = 0;
let res = "";
for (let seq in seqUsers) {
let size = seqUsers[seq].size;
if (size > maxCount || (size === maxCount && (res === "" || seq < res))) {
maxCount = size;
res = seq;
}
}
return res.split('|');
};