【Leetcode】1152. Analyze User Website Visit Pattern

题目地址:

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)

你可能感兴趣的:(#,栈,队列,串及其他数据结构,leetcode,数据结构,java,算法)