为了评估某网站的用户转化率,我们需要对用户的访问行为进行分析,并建立用户行为模型。日志文件中已经记录了用户名、访问时间 以及 页面路径。
为了方便分析,日志文件中的 N
条记录已经被解析成三个长度相同且长度都为 N
的数组,分别是:用户名 username
,访问时间 timestamp
和 页面路径 website
。第 i
条记录意味着用户名是 username[i]
的用户在 timestamp[i]
的时候访问了路径为 website[i]
的页面。
我们需要找到用户访问网站时的 『共性行为路径』,也就是有最多的用户都 至少按某种次序访问过一次 的三个页面路径。需要注意的是,用户 可能不是连续访问 这三个路径的。
『共性行为路径』是一个 长度为 3 的页面路径列表,列表中的路径 不必不同,并且按照访问时间的先后升序排列。
如果有多个满足要求的答案,那么就请返回按字典序排列最小的那个。(页面路径列表 X
按字典序小于 Y
的前提条件是:X[0] < Y[0]
或 X[0] == Y[0] 且 (X[1] < Y[1] 或 X[1] == Y[1] 且 X[2] < Y[2])
)
题目保证一个用户会至少访问 3 个路径一致的页面,并且一个用户不会在同一时间访问两个路径不同的页面。
示例:
输入: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"]
输出:["home","about","career"]
解释:
由示例输入得到的记录如下:
["joe", 1, "home"]
["joe", 2, "about"]
["joe", 3, "career"]
["james", 4, "home"]
["james", 5, "cart"]
["james", 6, "maps"]
["james", 7, "home"]
["mary", 8, "home"]
["mary", 9, "about"]
["mary", 10, "career"]
有 2 个用户至少访问过一次 ("home", "about", "career")。
有 1 个用户至少访问过一次 ("home", "cart", "maps")。
有 1 个用户至少访问过一次 ("home", "cart", "home")。
有 1 个用户至少访问过一次 ("home", "maps", "home")。
有 1 个用户至少访问过一次 ("cart", "maps", "home")。
提示:
3 <= N = username.length = timestamp.length = website.length <= 50
1 <= username[i].length <= 10
0 <= timestamp[i] <= 10^9
1 <= website[i].length <= 10
username[i]
和website[i]
都只含小写字符
思路:
先把每个人的访问列表按照顺序排好序,
然后统计一下这个人有哪些访问顺序,把对应的访问顺序出现的次数 + 1
比如 cat, map, mat, bat,访问顺序就有:
cat, map, mat
cat, map, bat
map, mat, bat
此题坑点在于,假设有一个人的访问顺序是这样的:
map, map, map, map, map, map,
实际上有效的访问顺序只有:
map, map, map
重复的访问顺序对于同一个人来说是无效的,
也就是说对于每一个人,对于一种访问顺序,只能做出 + 1 的贡献,这一点需要注意。
然后找到 出现次数最多的访问顺序,排好字典序之后返回下标为0的元素即可。
class Solution(object):
def mostVisitedPattern(self, username, timestamp, website):
"""
:type username: List[str]
:type timestamp: List[int]
:type website: List[str]
:rtype: List[str]
"""
from collections import defaultdict
record = defaultdict(list)
for i, un in enumerate(username):
record[un].append([timestamp[i], website[i]]) #对每个人建立档案
row = defaultdict(int)
for key in record.keys():
record[key].sort() #把每个人的记录按照时间排序
used = set()
for i in range(len(record[key])):
for j in range(i + 1, len(record[key])):
for k in range(j + 1, len(record[key])):
sequence = record[key][i][1] + "+" + record[key][j][1]+ "+" + record[key][k][1] #找到新的顺序组合
if sequence not in used: #避免同一个人的顺序发生重复
row[sequence] += 1
used.add(sequence)
# print row
possible_sol = []
max_freq = max(row.values())
for key, val in row.items():
if val == max_freq: #找到所有可能的解
possible_sol.append(key.split("+"))
possible_sol = possible_sol[::-1]
# print possible_sol
if len(possible_sol) > 1:
possible_sol.sort() #找到最终解,也就是字典序最小的那个解
return possible_sol[0]