From bfae6b932fed55c812117f0f8c1cac93ad735309 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 13 Aug 2024 10:04:36 +0800 Subject: [PATCH 1/2] feat: add solutions to lc problem: No.1311 No.1311.Get Watched Videos by Your Friends --- .../1310.XOR Queries of a Subarray/README.md | 38 ++-- .../README_EN.md | 49 ++-- .../Solution.js | 8 +- .../Solution.ts | 8 +- .../README.md | 207 +++++++++++++---- .../README_EN.md | 211 ++++++++++++++---- .../Solution.cpp | 37 +++ .../Solution.go | 36 +++ .../Solution.java | 46 ++-- .../Solution.py | 30 +-- .../Solution.ts | 37 +++ 11 files changed, 512 insertions(+), 195 deletions(-) create mode 100644 solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.cpp create mode 100644 solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.go create mode 100644 solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.ts diff --git a/solution/1300-1399/1310.XOR Queries of a Subarray/README.md b/solution/1300-1399/1310.XOR Queries of a Subarray/README.md index 8a45d8beb1435..995eb37827eee 100644 --- a/solution/1300-1399/1310.XOR Queries of a Subarray/README.md +++ b/solution/1300-1399/1310.XOR Queries of a Subarray/README.md @@ -32,17 +32,17 @@ tags:
 输入:arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
-输出:[2,7,14,8] 
+输出:[2,7,14,8]
 解释:
 数组中元素的二进制表示形式是:
-1 = 0001 
-3 = 0011 
-4 = 0100 
-8 = 1000 
+1 = 0001
+3 = 0011
+4 = 0100
+8 = 1000
 查询的 XOR 值为:
-[0,1] = 1 xor 3 = 2 
-[1,2] = 3 xor 4 = 7 
-[0,3] = 1 xor 3 xor 4 xor 8 = 14 
+[0,1] = 1 xor 3 = 2
+[1,2] = 3 xor 4 = 7
+[0,3] = 1 xor 3 xor 4 xor 8 = 14
 [3,3] = 8
 
@@ -73,18 +73,18 @@ tags: ### 方法一:前缀异或 -我们可以用一个长度为 $n+1$ 的前缀异或数组 $s$ 来存储数组 $arr$ 的前缀异或结果,其中 $s[i] = s[i-1] \oplus arr[i-1]$,即 $s[i]$ 表示 $arr$ 中下标 $[0,i-1]$ 的元素的异或结果。 +我们可以用一个长度为 $n+1$ 的前缀异或数组 $s$ 来存储数组 $\textit{arr}$ 的前缀异或结果,其中 $s[i] = s[i-1] \oplus \textit{arr}[i-1]$,即 $s[i]$ 表示 $\textit{arr}$ 的前 $i$ 个元素的异或结果。 那么对于一个查询 $[l,r]$,我们可以得到: $$ \begin{aligned} -arr[l] \oplus arr[l+1] \oplus \cdots \oplus arr[r] &= (arr[0] \oplus arr[1] \oplus \cdots \oplus arr[l-1]) \oplus (arr[0] \oplus arr[1] \oplus \cdots \oplus arr[r]) \\ +\textit{arr}[l] \oplus \textit{arr}[l+1] \oplus \cdots \oplus \textit{arr}[r] &= (\textit{arr}[0] \oplus \textit{arr}[1] \oplus \cdots \oplus \textit{arr}[l-1]) \oplus (\textit{arr}[0] \oplus \textit{arr}[1] \oplus \cdots \oplus \textit{arr}[r]) \\ &= s[l] \oplus s[r+1] \end{aligned} $$ -时间复杂度 $O(n+m)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是数组 $arr$ 和查询数组 $queries$ 的长度。 +时间复杂度 $O(n+m)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是数组 $\textit{arr}$ 的长度和查询数组 $\textit{queries}$ 的长度。 @@ -162,15 +162,11 @@ func xorQueries(arr []int, queries [][]int) (ans []int) { ```ts function xorQueries(arr: number[], queries: number[][]): number[] { const n = arr.length; - const s: number[] = new Array(n + 1).fill(0); + const s: number[] = Array(n + 1).fill(0); for (let i = 0; i < n; ++i) { s[i + 1] = s[i] ^ arr[i]; } - const ans: number[] = []; - for (const [l, r] of queries) { - ans.push(s[r + 1] ^ s[l]); - } - return ans; + return queries.map(([l, r]) => s[r + 1] ^ s[l]); } ``` @@ -184,15 +180,11 @@ function xorQueries(arr: number[], queries: number[][]): number[] { */ var xorQueries = function (arr, queries) { const n = arr.length; - const s = new Array(n + 1).fill(0); + const s = Array(n + 1).fill(0); for (let i = 0; i < n; ++i) { s[i + 1] = s[i] ^ arr[i]; } - const ans = []; - for (const [l, r] of queries) { - ans.push(s[r + 1] ^ s[l]); - } - return ans; + return queries.map(([l, r]) => s[r + 1] ^ s[l]); }; ``` diff --git a/solution/1300-1399/1310.XOR Queries of a Subarray/README_EN.md b/solution/1300-1399/1310.XOR Queries of a Subarray/README_EN.md index 53b49c510c7e8..6248180574046 100644 --- a/solution/1300-1399/1310.XOR Queries of a Subarray/README_EN.md +++ b/solution/1300-1399/1310.XOR Queries of a Subarray/README_EN.md @@ -31,17 +31,17 @@ tags:
 Input: arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
-Output: [2,7,14,8] 
-Explanation: 
+Output: [2,7,14,8]
+Explanation:
 The binary representation of the elements in the array are:
-1 = 0001 
-3 = 0011 
-4 = 0100 
-8 = 1000 
+1 = 0001
+3 = 0011
+4 = 0100
+8 = 1000
 The XOR values for queries are:
-[0,1] = 1 xor 3 = 2 
-[1,2] = 3 xor 4 = 7 
-[0,3] = 1 xor 3 xor 4 xor 8 = 14 
+[0,1] = 1 xor 3 = 2
+[1,2] = 3 xor 4 = 7
+[0,3] = 1 xor 3 xor 4 xor 8 = 14
 [3,3] = 8
 
@@ -68,7 +68,20 @@ The XOR values for queries are: -### Solution 1 +### Solution 1: Prefix XOR + +We can use a prefix XOR array $s$ of length $n+1$ to store the prefix XOR results of the array $\textit{arr}$, where $s[i] = s[i-1] \oplus \textit{arr}[i-1]$. That is, $s[i]$ represents the XOR result of the first $i$ elements of $\textit{arr}$. + +For a query $[l, r]$, we can obtain: + +$$ +\begin{aligned} +\textit{arr}[l] \oplus \textit{arr}[l+1] \oplus \cdots \oplus \textit{arr}[r] &= (\textit{arr}[0] \oplus \textit{arr}[1] \oplus \cdots \oplus \textit{arr}[l-1]) \oplus (\textit{arr}[0] \oplus \textit{arr}[1] \oplus \cdots \oplus \textit{arr}[r]) \\ +&= s[l] \oplus s[r+1] +\end{aligned} +$$ + +Time complexity is $O(n+m)$, and space complexity is $O(n)$. Here, $n$ and $m$ are the lengths of the array $\textit{arr}$ and the query array $\textit{queries}$, respectively. @@ -146,15 +159,11 @@ func xorQueries(arr []int, queries [][]int) (ans []int) { ```ts function xorQueries(arr: number[], queries: number[][]): number[] { const n = arr.length; - const s: number[] = new Array(n + 1).fill(0); + const s: number[] = Array(n + 1).fill(0); for (let i = 0; i < n; ++i) { s[i + 1] = s[i] ^ arr[i]; } - const ans: number[] = []; - for (const [l, r] of queries) { - ans.push(s[r + 1] ^ s[l]); - } - return ans; + return queries.map(([l, r]) => s[r + 1] ^ s[l]); } ``` @@ -168,15 +177,11 @@ function xorQueries(arr: number[], queries: number[][]): number[] { */ var xorQueries = function (arr, queries) { const n = arr.length; - const s = new Array(n + 1).fill(0); + const s = Array(n + 1).fill(0); for (let i = 0; i < n; ++i) { s[i + 1] = s[i] ^ arr[i]; } - const ans = []; - for (const [l, r] of queries) { - ans.push(s[r + 1] ^ s[l]); - } - return ans; + return queries.map(([l, r]) => s[r + 1] ^ s[l]); }; ``` diff --git a/solution/1300-1399/1310.XOR Queries of a Subarray/Solution.js b/solution/1300-1399/1310.XOR Queries of a Subarray/Solution.js index 4149f6a26f8f7..60a74b50d6e89 100644 --- a/solution/1300-1399/1310.XOR Queries of a Subarray/Solution.js +++ b/solution/1300-1399/1310.XOR Queries of a Subarray/Solution.js @@ -5,13 +5,9 @@ */ var xorQueries = function (arr, queries) { const n = arr.length; - const s = new Array(n + 1).fill(0); + const s = Array(n + 1).fill(0); for (let i = 0; i < n; ++i) { s[i + 1] = s[i] ^ arr[i]; } - const ans = []; - for (const [l, r] of queries) { - ans.push(s[r + 1] ^ s[l]); - } - return ans; + return queries.map(([l, r]) => s[r + 1] ^ s[l]); }; diff --git a/solution/1300-1399/1310.XOR Queries of a Subarray/Solution.ts b/solution/1300-1399/1310.XOR Queries of a Subarray/Solution.ts index 84677bc83d7fb..6c14df8493dd2 100644 --- a/solution/1300-1399/1310.XOR Queries of a Subarray/Solution.ts +++ b/solution/1300-1399/1310.XOR Queries of a Subarray/Solution.ts @@ -1,12 +1,8 @@ function xorQueries(arr: number[], queries: number[][]): number[] { const n = arr.length; - const s: number[] = new Array(n + 1).fill(0); + const s: number[] = Array(n + 1).fill(0); for (let i = 0; i < n; ++i) { s[i + 1] = s[i] ^ arr[i]; } - const ans: number[] = []; - for (const [l, r] of queries) { - ans.push(s[r + 1] ^ s[l]); - } - return ans; + return queries.map(([l, r]) => s[r + 1] ^ s[l]); } diff --git a/solution/1300-1399/1311.Get Watched Videos by Your Friends/README.md b/solution/1300-1399/1311.Get Watched Videos by Your Friends/README.md index 3bc2a6c5382ec..49d6548ab5ff1 100644 --- a/solution/1300-1399/1311.Get Watched Videos by Your Friends/README.md +++ b/solution/1300-1399/1311.Get Watched Videos by Your Friends/README.md @@ -37,7 +37,7 @@ tags:

输入:watchedVideos = [["A","B"],["C"],["B","C"],["D"]], friends = [[1,2],[0,3],[0,3],[1,2]], id = 0, level = 1
-输出:["B","C"] 
+输出:["B","C"]
 解释:
 你的 id 为 0(绿色),你的朋友包括(黄色):
 id 为 1 -> watchedVideos = ["C"] 
@@ -79,7 +79,15 @@ C -> 2
 
 
 
-### 方法一
+### 方法一:BFS
+
+我们可以使用广度优先搜索的方法,从 $\textit{id}$ 出发,找到所有距离为 $\textit{level}$ 的好友,然后统计这些好友观看的视频。
+
+具体地,我们可以使用一个队列 $\textit{q}$ 来存储当前层的好友,初始时将 $\textit{id}$ 加入队列 $\textit{q}$ 中,用一个哈希表或者布尔数组 $\textit{vis}$ 来记录已经访问过的好友,然后进行 $\textit{level}$ 次循环,每次循环将队列中的所有好友出队,并将他们的好友加入队列,直到找到所有距禒为 $\textit{level}$ 的好友。
+
+然后,我们使用一个哈希表 $\textit{cnt}$ 来统计这些好友观看的视频及其频率,最后将哈希表中的键值对按照频率升序排序,如果频率相同,则按照视频名称升序排序。最后返回排序后的视频名称列表。
+
+时间复杂度 $O(n + m + v \times \log v)$,空间复杂度 $O(n + v)$。其中 $n$ 和 $m$ 分别是数组 $\textit{watchedVideos}$ 和 $\textit{friends}$ 的长度,而 $v$ 是所有好友观看的视频数量。
 
 
 
@@ -94,72 +102,181 @@ class Solution:
         id: int,
         level: int,
     ) -> List[str]:
-        n = len(friends)
-        vis = [False] * n
         q = deque([id])
-        vis[id] = True
+        vis = {id}
         for _ in range(level):
-            size = len(q)
-            for _ in range(size):
-                u = q.popleft()
-                for v in friends[u]:
-                    if not vis[v]:
-                        q.append(v)
-                        vis[v] = True
-        freq = Counter()
-        for _ in range(len(q)):
-            u = q.pop()
-            for w in watchedVideos[u]:
-                freq[w] += 1
-        videos = list(freq.items())
-        videos.sort(key=lambda x: (x[1], x[0]))
-        return [v[0] for v in videos]
+            for _ in range(len(q)):
+                i = q.popleft()
+                for j in friends[i]:
+                    if j not in vis:
+                        vis.add(j)
+                        q.append(j)
+        cnt = Counter()
+        for i in q:
+            for v in watchedVideos[i]:
+                cnt[v] += 1
+        return sorted(cnt.keys(), key=lambda k: (cnt[k], k))
 ```
 
 #### Java
 
 ```java
 class Solution {
-    public List watchedVideosByFriends(
-        List> watchedVideos, int[][] friends, int id, int level) {
+    public List watchedVideosByFriends(List> watchedVideos, int[][] friends, int id, int level) {
+        Deque q = new ArrayDeque<>();
+        q.offer(id);
         int n = friends.length;
         boolean[] vis = new boolean[n];
-        Deque q = new LinkedList<>();
-        q.offerLast(id);
         vis[id] = true;
         while (level-- > 0) {
-            for (int i = q.size(); i > 0; --i) {
-                int u = q.pollFirst();
-                for (int v : friends[u]) {
-                    if (!vis[v]) {
-                        q.offerLast(v);
-                        vis[v] = true;
+            for (int k = q.size(); k > 0; --k) {
+                int i = q.poll();
+                for (int j : friends[i]) {
+                    if (!vis[j]) {
+                        vis[j] = true;
+                        q.offer(j);
                     }
                 }
             }
         }
-        Map freq = new HashMap<>();
-        while (!q.isEmpty()) {
-            for (String w : watchedVideos.get(q.pollFirst())) {
-                freq.put(w, freq.getOrDefault(w, 0) + 1);
+        Map cnt = new HashMap<>();
+        for (int i : q) {
+            for (var v : watchedVideos.get(i)) {
+                cnt.merge(v, 1, Integer::sum);
             }
         }
-        List> t = new ArrayList<>(freq.entrySet());
-        t.sort((a, b) -> {
-            if (a.getValue() > b.getValue()) {
-                return 1;
+        List ans = new ArrayList<>(cnt.keySet());
+        ans.sort((a, b) -> {
+            int x = cnt.get(a), y = cnt.get(b);
+            return x == y ? a.compareTo(b) : Integer.compare(x, y);
+        });
+        return ans;
+    }
+}
+```
+
+#### C++
+
+```cpp
+class Solution {
+public:
+    vector watchedVideosByFriends(vector>& watchedVideos, vector>& friends, int id, int level) {
+        queue q{{id}};
+        int n = friends.size();
+        vector vis(n);
+        vis[id] = true;
+        while (level--) {
+            for (int k = q.size(); k; --k) {
+                int i = q.front();
+                q.pop();
+                for (int j : friends[i]) {
+                    if (!vis[j]) {
+                        vis[j] = true;
+                        q.push(j);
+                    }
+                }
             }
-            if (a.getValue() < b.getValue()) {
-                return -1;
+        }
+        unordered_map cnt;
+        while (!q.empty()) {
+            int i = q.front();
+            q.pop();
+            for (const auto& v : watchedVideos[i]) {
+                cnt[v]++;
             }
-            return a.getKey().compareTo(b.getKey());
-        });
-        List ans = new ArrayList<>();
-        for (Map.Entry e : t) {
-            ans.add(e.getKey());
         }
+        vector ans;
+        for (const auto& [key, _] : cnt) {
+            ans.push_back(key);
+        }
+        sort(ans.begin(), ans.end(), [&cnt](const string& a, const string& b) {
+            return cnt[a] == cnt[b] ? a < b : cnt[a] < cnt[b];
+        });
         return ans;
     }
+};
+```
+
+#### Go
+
+```go
+func watchedVideosByFriends(watchedVideos [][]string, friends [][]int, id int, level int) []string {
+	q := []int{id}
+	n := len(friends)
+	vis := make([]bool, n)
+	vis[id] = true
+	for level > 0 {
+		level--
+		nextQ := []int{}
+		for _, i := range q {
+			for _, j := range friends[i] {
+				if !vis[j] {
+					vis[j] = true
+					nextQ = append(nextQ, j)
+				}
+			}
+		}
+		q = nextQ
+	}
+	cnt := make(map[string]int)
+	for _, i := range q {
+		for _, v := range watchedVideos[i] {
+			cnt[v]++
+		}
+	}
+	ans := []string{}
+	for key := range cnt {
+		ans = append(ans, key)
+	}
+	sort.Slice(ans, func(i, j int) bool {
+		if cnt[ans[i]] == cnt[ans[j]] {
+			return ans[i] < ans[j]
+		}
+		return cnt[ans[i]] < cnt[ans[j]]
+	})
+	return ans
+}
+```
+
+#### TypeScript
+
+```ts
+function watchedVideosByFriends(
+    watchedVideos: string[][],
+    friends: number[][],
+    id: number,
+    level: number,
+): string[] {
+    let q: number[] = [id];
+    const n: number = friends.length;
+    const vis: boolean[] = Array(n).fill(false);
+    vis[id] = true;
+    while (level-- > 0) {
+        const nq: number[] = [];
+        for (const i of q) {
+            for (const j of friends[i]) {
+                if (!vis[j]) {
+                    vis[j] = true;
+                    nq.push(j);
+                }
+            }
+        }
+        q = nq;
+    }
+    const cnt: { [key: string]: number } = {};
+    for (const i of q) {
+        for (const v of watchedVideos[i]) {
+            cnt[v] = (cnt[v] || 0) + 1;
+        }
+    }
+    const ans: string[] = Object.keys(cnt);
+    ans.sort((a, b) => {
+        if (cnt[a] === cnt[b]) {
+            return a.localeCompare(b);
+        }
+        return cnt[a] - cnt[b];
+    });
+    return ans;
 }
 ```
 
diff --git a/solution/1300-1399/1311.Get Watched Videos by Your Friends/README_EN.md b/solution/1300-1399/1311.Get Watched Videos by Your Friends/README_EN.md
index 9db5bcfb0808e..613348db9322e 100644
--- a/solution/1300-1399/1311.Get Watched Videos by Your Friends/README_EN.md	
+++ b/solution/1300-1399/1311.Get Watched Videos by Your Friends/README_EN.md	
@@ -33,8 +33,8 @@ tags:
 
 
 Input: watchedVideos = [["A","B"],["C"],["B","C"],["D"]], friends = [[1,2],[0,3],[0,3],[1,2]], id = 0, level = 1
-Output: ["B","C"] 
-Explanation: 
+Output: ["B","C"]
+Explanation:
 You have id = 0 (green color in the figure) and your friends are (yellow color in the figure):
 Person with id = 1 -> watchedVideos = ["C"] 
 Person with id = 2 -> watchedVideos = ["B","C"] 
@@ -50,7 +50,7 @@ C -> 2
 
 Input: watchedVideos = [["A","B"],["C"],["B","C"],["D"]], friends = [[1,2],[0,3],[0,3],[1,2]], id = 0, level = 2
 Output: ["D"]
-Explanation: 
+Explanation:
 You have id = 0 (green color in the figure) and the only friend of your friends is the person with id = 3 (yellow color in the figure).
 
@@ -75,7 +75,15 @@ You have id = 0 (green color in the figure) and the only friend of your friends -### Solution 1 +### Solution 1: BFS + +We can use the Breadth-First Search (BFS) method to start from $\textit{id}$ and find all friends at a distance of $\textit{level}$, then count the videos watched by these friends. + +Specifically, we can use a queue $\textit{q}$ to store the friends at the current level. Initially, add $\textit{id}$ to the queue $\textit{q}$. Use a hash table or a boolean array $\textit{vis}$ to record the friends that have already been visited. Then, perform $\textit{level}$ iterations, in each iteration dequeue all friends from the queue and enqueue their friends until all friends at distance $\textit{level}$ are found. + +Next, we use a hash table $\textit{cnt}$ to count the videos watched by these friends and their frequencies. Finally, sort the key-value pairs in the hash table in ascending order by frequency, and if frequencies are the same, sort by video name in ascending order. Return the sorted list of video names. + +Time complexity is $O(n + m + v \times \log v)$, and space complexity is $O(n + v)$. Here, $n$ and $m$ are the lengths of the arrays $\textit{watchedVideos}$ and $\textit{friends}$, respectively, and $v$ is the total number of videos watched by all friends. @@ -90,72 +98,181 @@ class Solution: id: int, level: int, ) -> List[str]: - n = len(friends) - vis = [False] * n q = deque([id]) - vis[id] = True + vis = {id} for _ in range(level): - size = len(q) - for _ in range(size): - u = q.popleft() - for v in friends[u]: - if not vis[v]: - q.append(v) - vis[v] = True - freq = Counter() - for _ in range(len(q)): - u = q.pop() - for w in watchedVideos[u]: - freq[w] += 1 - videos = list(freq.items()) - videos.sort(key=lambda x: (x[1], x[0])) - return [v[0] for v in videos] + for _ in range(len(q)): + i = q.popleft() + for j in friends[i]: + if j not in vis: + vis.add(j) + q.append(j) + cnt = Counter() + for i in q: + for v in watchedVideos[i]: + cnt[v] += 1 + return sorted(cnt.keys(), key=lambda k: (cnt[k], k)) ``` #### Java ```java class Solution { - public List watchedVideosByFriends( - List> watchedVideos, int[][] friends, int id, int level) { + public List watchedVideosByFriends(List> watchedVideos, int[][] friends, int id, int level) { + Deque q = new ArrayDeque<>(); + q.offer(id); int n = friends.length; boolean[] vis = new boolean[n]; - Deque q = new LinkedList<>(); - q.offerLast(id); vis[id] = true; while (level-- > 0) { - for (int i = q.size(); i > 0; --i) { - int u = q.pollFirst(); - for (int v : friends[u]) { - if (!vis[v]) { - q.offerLast(v); - vis[v] = true; + for (int k = q.size(); k > 0; --k) { + int i = q.poll(); + for (int j : friends[i]) { + if (!vis[j]) { + vis[j] = true; + q.offer(j); } } } } - Map freq = new HashMap<>(); - while (!q.isEmpty()) { - for (String w : watchedVideos.get(q.pollFirst())) { - freq.put(w, freq.getOrDefault(w, 0) + 1); + Map cnt = new HashMap<>(); + for (int i : q) { + for (var v : watchedVideos.get(i)) { + cnt.merge(v, 1, Integer::sum); } } - List> t = new ArrayList<>(freq.entrySet()); - t.sort((a, b) -> { - if (a.getValue() > b.getValue()) { - return 1; + List ans = new ArrayList<>(cnt.keySet()); + ans.sort((a, b) -> { + int x = cnt.get(a), y = cnt.get(b); + return x == y ? a.compareTo(b) : Integer.compare(x, y); + }); + return ans; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + vector watchedVideosByFriends(vector>& watchedVideos, vector>& friends, int id, int level) { + queue q{{id}}; + int n = friends.size(); + vector vis(n); + vis[id] = true; + while (level--) { + for (int k = q.size(); k; --k) { + int i = q.front(); + q.pop(); + for (int j : friends[i]) { + if (!vis[j]) { + vis[j] = true; + q.push(j); + } + } } - if (a.getValue() < b.getValue()) { - return -1; + } + unordered_map cnt; + while (!q.empty()) { + int i = q.front(); + q.pop(); + for (const auto& v : watchedVideos[i]) { + cnt[v]++; } - return a.getKey().compareTo(b.getKey()); - }); - List ans = new ArrayList<>(); - for (Map.Entry e : t) { - ans.add(e.getKey()); } + vector ans; + for (const auto& [key, _] : cnt) { + ans.push_back(key); + } + sort(ans.begin(), ans.end(), [&cnt](const string& a, const string& b) { + return cnt[a] == cnt[b] ? a < b : cnt[a] < cnt[b]; + }); return ans; } +}; +``` + +#### Go + +```go +func watchedVideosByFriends(watchedVideos [][]string, friends [][]int, id int, level int) []string { + q := []int{id} + n := len(friends) + vis := make([]bool, n) + vis[id] = true + for level > 0 { + level-- + nextQ := []int{} + for _, i := range q { + for _, j := range friends[i] { + if !vis[j] { + vis[j] = true + nextQ = append(nextQ, j) + } + } + } + q = nextQ + } + cnt := make(map[string]int) + for _, i := range q { + for _, v := range watchedVideos[i] { + cnt[v]++ + } + } + ans := []string{} + for key := range cnt { + ans = append(ans, key) + } + sort.Slice(ans, func(i, j int) bool { + if cnt[ans[i]] == cnt[ans[j]] { + return ans[i] < ans[j] + } + return cnt[ans[i]] < cnt[ans[j]] + }) + return ans +} +``` + +#### TypeScript + +```ts +function watchedVideosByFriends( + watchedVideos: string[][], + friends: number[][], + id: number, + level: number, +): string[] { + let q: number[] = [id]; + const n: number = friends.length; + const vis: boolean[] = Array(n).fill(false); + vis[id] = true; + while (level-- > 0) { + const nq: number[] = []; + for (const i of q) { + for (const j of friends[i]) { + if (!vis[j]) { + vis[j] = true; + nq.push(j); + } + } + } + q = nq; + } + const cnt: { [key: string]: number } = {}; + for (const i of q) { + for (const v of watchedVideos[i]) { + cnt[v] = (cnt[v] || 0) + 1; + } + } + const ans: string[] = Object.keys(cnt); + ans.sort((a, b) => { + if (cnt[a] === cnt[b]) { + return a.localeCompare(b); + } + return cnt[a] - cnt[b]; + }); + return ans; } ``` diff --git a/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.cpp b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.cpp new file mode 100644 index 0000000000000..7b44db5a0c785 --- /dev/null +++ b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.cpp @@ -0,0 +1,37 @@ +class Solution { +public: + vector watchedVideosByFriends(vector>& watchedVideos, vector>& friends, int id, int level) { + queue q{{id}}; + int n = friends.size(); + vector vis(n); + vis[id] = true; + while (level--) { + for (int k = q.size(); k; --k) { + int i = q.front(); + q.pop(); + for (int j : friends[i]) { + if (!vis[j]) { + vis[j] = true; + q.push(j); + } + } + } + } + unordered_map cnt; + while (!q.empty()) { + int i = q.front(); + q.pop(); + for (const auto& v : watchedVideos[i]) { + cnt[v]++; + } + } + vector ans; + for (const auto& [key, _] : cnt) { + ans.push_back(key); + } + sort(ans.begin(), ans.end(), [&cnt](const string& a, const string& b) { + return cnt[a] == cnt[b] ? a < b : cnt[a] < cnt[b]; + }); + return ans; + } +}; diff --git a/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.go b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.go new file mode 100644 index 0000000000000..02a443655527b --- /dev/null +++ b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.go @@ -0,0 +1,36 @@ +func watchedVideosByFriends(watchedVideos [][]string, friends [][]int, id int, level int) []string { + q := []int{id} + n := len(friends) + vis := make([]bool, n) + vis[id] = true + for level > 0 { + level-- + nextQ := []int{} + for _, i := range q { + for _, j := range friends[i] { + if !vis[j] { + vis[j] = true + nextQ = append(nextQ, j) + } + } + } + q = nextQ + } + cnt := make(map[string]int) + for _, i := range q { + for _, v := range watchedVideos[i] { + cnt[v]++ + } + } + ans := []string{} + for key := range cnt { + ans = append(ans, key) + } + sort.Slice(ans, func(i, j int) bool { + if cnt[ans[i]] == cnt[ans[j]] { + return ans[i] < ans[j] + } + return cnt[ans[i]] < cnt[ans[j]] + }) + return ans +} diff --git a/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.java b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.java index df075cdf37755..58bc2db43220f 100644 --- a/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.java +++ b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.java @@ -1,42 +1,32 @@ class Solution { - public List watchedVideosByFriends( - List> watchedVideos, int[][] friends, int id, int level) { + public List watchedVideosByFriends(List> watchedVideos, int[][] friends, int id, int level) { + Deque q = new ArrayDeque<>(); + q.offer(id); int n = friends.length; boolean[] vis = new boolean[n]; - Deque q = new LinkedList<>(); - q.offerLast(id); vis[id] = true; while (level-- > 0) { - for (int i = q.size(); i > 0; --i) { - int u = q.pollFirst(); - for (int v : friends[u]) { - if (!vis[v]) { - q.offerLast(v); - vis[v] = true; + for (int k = q.size(); k > 0; --k) { + int i = q.poll(); + for (int j : friends[i]) { + if (!vis[j]) { + vis[j] = true; + q.offer(j); } } } } - Map freq = new HashMap<>(); - while (!q.isEmpty()) { - for (String w : watchedVideos.get(q.pollFirst())) { - freq.put(w, freq.getOrDefault(w, 0) + 1); + Map cnt = new HashMap<>(); + for (int i : q) { + for (var v : watchedVideos.get(i)) { + cnt.merge(v, 1, Integer::sum); } } - List> t = new ArrayList<>(freq.entrySet()); - t.sort((a, b) -> { - if (a.getValue() > b.getValue()) { - return 1; - } - if (a.getValue() < b.getValue()) { - return -1; - } - return a.getKey().compareTo(b.getKey()); + List ans = new ArrayList<>(cnt.keySet()); + ans.sort((a, b) -> { + int x = cnt.get(a), y = cnt.get(b); + return x == y ? a.compareTo(b) : Integer.compare(x, y); }); - List ans = new ArrayList<>(); - for (Map.Entry e : t) { - ans.add(e.getKey()); - } return ans; } -} \ No newline at end of file +} diff --git a/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.py b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.py index 41684ebc96406..6ff97cb7bbab6 100644 --- a/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.py +++ b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.py @@ -6,23 +6,17 @@ def watchedVideosByFriends( id: int, level: int, ) -> List[str]: - n = len(friends) - vis = [False] * n q = deque([id]) - vis[id] = True + vis = {id} for _ in range(level): - size = len(q) - for _ in range(size): - u = q.popleft() - for v in friends[u]: - if not vis[v]: - q.append(v) - vis[v] = True - freq = Counter() - for _ in range(len(q)): - u = q.pop() - for w in watchedVideos[u]: - freq[w] += 1 - videos = list(freq.items()) - videos.sort(key=lambda x: (x[1], x[0])) - return [v[0] for v in videos] + for _ in range(len(q)): + i = q.popleft() + for j in friends[i]: + if j not in vis: + vis.add(j) + q.append(j) + cnt = Counter() + for i in q: + for v in watchedVideos[i]: + cnt[v] += 1 + return sorted(cnt.keys(), key=lambda k: (cnt[k], k)) diff --git a/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.ts b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.ts new file mode 100644 index 0000000000000..8ab4e2304a195 --- /dev/null +++ b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.ts @@ -0,0 +1,37 @@ +function watchedVideosByFriends( + watchedVideos: string[][], + friends: number[][], + id: number, + level: number, +): string[] { + let q: number[] = [id]; + const n: number = friends.length; + const vis: boolean[] = Array(n).fill(false); + vis[id] = true; + while (level-- > 0) { + const nq: number[] = []; + for (const i of q) { + for (const j of friends[i]) { + if (!vis[j]) { + vis[j] = true; + nq.push(j); + } + } + } + q = nq; + } + const cnt: { [key: string]: number } = {}; + for (const i of q) { + for (const v of watchedVideos[i]) { + cnt[v] = (cnt[v] || 0) + 1; + } + } + const ans: string[] = Object.keys(cnt); + ans.sort((a, b) => { + if (cnt[a] === cnt[b]) { + return a.localeCompare(b); + } + return cnt[a] - cnt[b]; + }); + return ans; +} From 280be8be2edb6bcce4e87f16fa11fb7a83357e89 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 13 Aug 2024 11:20:02 +0800 Subject: [PATCH 2/2] fix: update --- .../1311.Get Watched Videos by Your Friends/README.md | 3 ++- .../1311.Get Watched Videos by Your Friends/README_EN.md | 3 ++- .../1311.Get Watched Videos by Your Friends/Solution.java | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/solution/1300-1399/1311.Get Watched Videos by Your Friends/README.md b/solution/1300-1399/1311.Get Watched Videos by Your Friends/README.md index 49d6548ab5ff1..05386d827a14c 100644 --- a/solution/1300-1399/1311.Get Watched Videos by Your Friends/README.md +++ b/solution/1300-1399/1311.Get Watched Videos by Your Friends/README.md @@ -122,7 +122,8 @@ class Solution: ```java class Solution { - public List watchedVideosByFriends(List> watchedVideos, int[][] friends, int id, int level) { + public List watchedVideosByFriends( + List> watchedVideos, int[][] friends, int id, int level) { Deque q = new ArrayDeque<>(); q.offer(id); int n = friends.length; diff --git a/solution/1300-1399/1311.Get Watched Videos by Your Friends/README_EN.md b/solution/1300-1399/1311.Get Watched Videos by Your Friends/README_EN.md index 613348db9322e..1e52f27b051a5 100644 --- a/solution/1300-1399/1311.Get Watched Videos by Your Friends/README_EN.md +++ b/solution/1300-1399/1311.Get Watched Videos by Your Friends/README_EN.md @@ -118,7 +118,8 @@ class Solution: ```java class Solution { - public List watchedVideosByFriends(List> watchedVideos, int[][] friends, int id, int level) { + public List watchedVideosByFriends( + List> watchedVideos, int[][] friends, int id, int level) { Deque q = new ArrayDeque<>(); q.offer(id); int n = friends.length; diff --git a/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.java b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.java index 58bc2db43220f..68fd3190912bc 100644 --- a/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.java +++ b/solution/1300-1399/1311.Get Watched Videos by Your Friends/Solution.java @@ -1,5 +1,6 @@ class Solution { - public List watchedVideosByFriends(List> watchedVideos, int[][] friends, int id, int level) { + public List watchedVideosByFriends( + List> watchedVideos, int[][] friends, int id, int level) { Deque q = new ArrayDeque<>(); q.offer(id); int n = friends.length;