【Leetcode】1152. Analyze User Website Visit Pattern

该博客介绍了一道LeetCode上的问题,涉及用户网站访问模式的统计。作者首先创建了一个`Visit`类来存储用户、时间戳和网站信息,并按时间戳排序。接着,使用哈希表记录每个用户的网站访问序列,并通过三重循环枚举所有可能的三元组,对每个三元组进行计数。最后,找到出现次数最多且字典序最小的三元组。代码的时间复杂度为O(n^3),空间复杂度为O(n)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目地址:

https://leetcode.com/problems/analyze-user-website-visit-pattern/

给定三个等长的数组,数组 A A A是一系列用户,数组 B B B是这些用户访问网站的时间戳,数组 C C C是用户访问的网站。某个用户按时间依次访问的网站如果长度 l l l大于 3 3 3,就可以取出 ( l 3 ) l\choose3 (3l)个三元组。问这些三元组里被最多用户访问过的组合是哪个。如果答案有多个则返回字典序最小的那个三元组。题目保证至少有一个用户访问了三个或以上的网站。

先将用户、时间戳和网站做成一个类,然后按照时间戳排序,再用一个哈希表存一下每个用户访问网站的序列。接着对每个用户,枚举三元组,并对三元组计数。注意,同一个三元组对同一个用户而言,只能计数一次。最后查找一下计数次数最多、字典序最小的三元组即可。代码如下:

import java.util.*;

public class Solution {
    
    class Visit {
        String username, website;
        int timestamp;
        
        public Visit(String username, String website, int timestamp) {
            this.username = username;
            this.website = website;
            this.timestamp = timestamp;
        }
    }
    
    public List<String> mostVisitedPattern(String[] username, int[] timestamp, String[] website) {
        int n = username.length;
        // 先存一下Visit,然后对其按照时间戳排序
        List<Visit> list = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            list.add(new Visit(username[i], website[i], timestamp[i]));
        }
        list.sort((v1, v2) -> Integer.compare(v1.timestamp, v2.timestamp));
        
        // 存一下每个用户访问网站的序列
        Map<String, List<String>> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            Visit visit = list.get(i);
            map.putIfAbsent(visit.username, new ArrayList<>());
            map.get(visit.username).add(visit.website);
        }
        
        // 对每个用户枚举三元组
        Map<List<String>, Integer> count = new HashMap<>();
        for (Map.Entry<String, List<String>> entry : map.entrySet()) {
            List<String> webList = entry.getValue();
            if (webList.size() >= 3) {
            	// 这里对三元组要去重,因为他们的计数只能加1
                Set<List<String>> set = new HashSet<>();
                for (int i = 0; i < webList.size() - 2; i++) {
                    for (int j = i + 1; j < webList.size() - 1; j++) {
                        for (int k = j + 1; k < webList.size(); k++) {
                            List<String> tuple = Arrays.asList(webList.get(i), webList.get(j), webList.get(k));
                            set.add(tuple);
                        }
                    }
                }
                
                // 在哈希表里的计数加1
                for (List<String> tuple : set) {
                    count.put(tuple, count.getOrDefault(tuple, 0) + 1);
                }
            }
        }
        
        // 最后找一下出现次数最多、字典序最小的三元组
        List<String> res = new ArrayList<>();
        int maxCount = 0;
        for (Map.Entry<List<String>, Integer> entry : count.entrySet()) {
            if (entry.getValue() > maxCount) {
                maxCount = entry.getValue();
                res = entry.getKey();
            } else if (entry.getValue() == maxCount && compare(entry.getKey(), res) < 0) {
                res = entry.getKey();
            }
        }
        
        return res;
    }
    
    private int compare(List<String> l1, List<String> l2) {
        for (int i = 0; i < 3; i++) {
            int comp = l1.get(i).compareTo(l2.get(i));
            if (comp != 0) {
                return comp;
            }
        }
        
        return 0;
    }
}

时间复杂度 O ( n 3 ) O(n^3) O(n3) n n n是数组长度,空间 O ( n ) O(n) O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值