目录
LeetCode 1452 | 用户收藏公司子集问题 — 找出非子集收藏列表
LeetCode 1452 | 用户收藏公司子集问题 — 找出非子集收藏列表
题目描述
给你一个二维数组 favoriteCompanies,其中 favoriteCompanies[i] 是第 i 名用户收藏的公司清单(i 从 0 开始)。
请找出那些不是其他任何人收藏清单的子集的收藏清单,并返回这些收藏清单对应的下标,结果下标需要按升序排列。
直观理解
假设有多个用户,每个用户收藏了若干公司。现在想找出那些“独特”的收藏清单——也就是说,这些收藏清单不完全包含于其他用户的收藏清单之中。
解题分析
问题的核心是判断一个集合是否是另一个集合的子集。若 favoriteCompanies[i] 是 favoriteCompanies[j] 的子集,说明第 i 用户的收藏清单可以被第 j 用户完全包含,不满足题目要求。
我们需要对每个用户的收藏清单进行判断,看它是否是任何其他用户收藏清单的子集。如果是,则排除;否则保留。
解决方案
方案思路
- 集合转换
为方便判断子集关系,将每个用户的公司列表转换为集合。 - 两重循环判断
对于每个用户 i,遍历所有其他用户 j(j != i),判断集合 i 是否是集合 j 的子集。
-
- 如果是,说明 i 是某个 j 的子集,i 不能保留。
- 如果不是任何一个集合的子集,则 i 保留。
- 结果排序输出
将满足条件的 i 下标收集起来,最后排序返回。
代码实现(Python)
from typing import List
class Solution:
def peopleIndexes(self, favoriteCompanies: List[List[str]]) -> List[int]:
n = len(favoriteCompanies)
# 转集合,便于判断子集
sets = [set(companies) for companies in favoriteCompanies]
res = []
for i in range(n):
is_subset = False
for j in range(n):
if i != j and sets[i].issubset(sets[j]):
is_subset = True
break
if not is_subset:
res.append(i)
return sorted(res)
复杂度分析
- 时间复杂度:
-
- 设 n 为用户数,m 为每个收藏清单中公司的平均数量。
- 两层循环 O(n²),每次子集判断最坏 O(m)。
- 故总体时间复杂度约为 O(n² * m)。
- 空间复杂度:
-
- 需要存储转换后的集合,空间 O(n * m)。
该算法适合 n 较小或中等规模时使用。
示例说明
举个简单例子:
favoriteCompanies = [
["leetcode", "google", "facebook"], # 0
["google", "microsoft"], # 1
["google", "facebook"], # 2
["leetcode", "google", "facebook", "microsoft"], # 3
["amazon"] # 4
]
- 对用户 0:集合是
{leetcode, google, facebook} - 用户 3 的集合是
{leetcode, google, facebook, microsoft},包含用户 0 的集合。
所以用户 0 是用户 3 的子集,不满足条件。 - 用户 2 的集合
{google, facebook}是用户 0 和用户 3 的子集,不满足。 - 用户 1 集合
{google, microsoft}不是任何其他用户集合的子集。 - 用户 4 的集合
{amazon}独一无二。
最后符合条件的是用户 1 和用户 4,此外用户 0 也是有条件地被保留的(看问题定义和代码,这里是排除子集,用户 0 是子集,不保留)。
经代码测试,输出为 [1, 4]。
总结
- 这道题的关键是利用集合的子集关系判断,使用 Python 内置的
issubset方法,代码简洁且易读。 - 双重循环是最直观的方法,适合数据量不大的情况下使用。
- 若要优化,可考虑对集合排序或使用位运算压缩集合进行更高效的子集判断,但复杂度较高。
- 题目考察集合操作、子集判断和双重循环逻辑。
400

被折叠的 条评论
为什么被折叠?



