JavaInterview JavaInterview
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)

『Java面试+Java学习』
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)
  • 指南
  • 简历

  • Java

  • 面试

  • 算法

  • algorithm
  • leetcode
JavaInterview.cn
2024-09-28
目录

获取你好友已观看的视频Java

文章发布较早,内容可能过时,阅读注意甄别。

# 题目

有 n 个人,每个人都有一个 0 到 n-1 的唯一 id 。

给你数组 watchedVideos 和 friends ,其中 watchedVideos[i] 和 friends[i] 分别表示 id = i 的人观看过的视频列表和他的好友列表。

Level 1 的视频包含所有你好友观看过的视频,level 2 的视频包含所有你好友的好友观看过的视频,以此类推。一般的,Level 为 k 的视频包含所有从你出发,最短距离为 k 的好友观看过的视频。

给定你的 id 和一个 level 值,请你找出所有指定 level 的视频,并将它们按观看频率升序返回。如果有频率相同的视频,请将它们按字母顺序从小到大排列。

示例 1: leetcode_friends_1.png

输入:watchedVideos = [["A","B"],["C"],["B","C"],["D"]], friends = [[1,2],[0,3],[0,3],[1,2]], id = 0, level = 1
输出:["B","C"]
解释:
你的 id 为 0(绿色),你的朋友包括(黄色):
id 为 1 -> watchedVideos = ["C"]
id 为 2 -> watchedVideos = ["B","C"]
你朋友观看过视频的频率为:
B -> 1
C -> 2

示例 2:

leetcode_friends_2.png

输入:watchedVideos = [["A","B"],["C"],["B","C"],["D"]], friends = [[1,2],[0,3],[0,3],[1,2]], id = 0, level = 2
输出:["D"]
解释:
你的 id 为 0(绿色),你朋友的朋友只有一个人,他的 id 为 3(黄色)。

提示:

  • n == watchedVideos.length == friends.length
  • 2 <= n <= 100
  • 1 <= watchedVideos[i].length <= 100
  • 1 <= watchedVideos[i][j].length <= 8
  • 0 <= friends[i].length < n
  • 0 <= friends[i][j] < n
  • 0 <= id < n
  • 1 <= level < n
  • 如果 friends[i] 包含 j ,那么 friends[j] 包含 i

# 思路

bfs

# 解法

class Solution {

    public List<String> watchedVideosByFriends(List<List<String>> watchedVideos, int[][] friends, int id, int level) {
        Deque<Integer> queue = new LinkedList<>();
        Set<Integer> seen = new HashSet<>();
        queue.offer(id);
        seen.add(id);
        int curLevel = 0;
        
        // 求第k层的问题,使用广度遍历, 由于是无向图。使用集合保证遍历的方向性。
        while(!queue.isEmpty() && curLevel <= level){
            int size = queue.size();

            if (curLevel == level){
                return getFriendVideos(queue, watchedVideos);
            }

            for(int idx = 0;idx < size;idx++) {
                int userId = queue.poll();
                for(int friendId: friends[userId]){
                    if (seen.contains(friendId)) continue;
                    queue.offer(friendId);
                    seen.add(friendId);
                }
            }

            curLevel += 1;
        }

        //level是不对的。超出了最大深度或为负数。抛出异常。
        throw new IllegalArgumentException("level is not valid");
    }

    private List<String> getFriendVideos(Deque<Integer> friendIds, List<List<String>> watchedVideos){

        Map<String,Integer> map = new HashMap<>();
        List<String> videos = new ArrayList<>();
        Iterator<Integer> it = friendIds.iterator();

        // 遍历第k层所有好友的id,并遍历他们看得视频, 统计个数到哈希表中。
        while(it.hasNext()){
            int id = it.next();
            for(String video : watchedVideos.get(id)){
                map.put(video, map.getOrDefault(video,0) + 1);
            }
        }

        // 将所有的视频添加到map中。
        for(String video : map.keySet()){
            videos.add(video);
        }

        // 按观看频率升序返回,如果存在频率相同的视频按名字字典序从小到大排列
        Collections.sort(videos, (v1, v2) ->{
            if ( map.get(v1) - map.get(v2) == 0 ) {
                return v1.compareTo(v2);
            }
            return map.get(v1) - map.get(v2);
        });

        return videos;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

# 总结

  • 分析出几种情况,然后分别对各个情况实现
微信 支付宝
#Java
最近更新
01
1686. 石子游戏VI Java
08-18
02
1688. 比赛中的配对次数 Java
08-18
03
1687. 从仓库到码头运输箱子 Java
08-18
更多文章>
Theme by Vdoing | Copyright © 2019-2025 JavaInterview.cn
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式