题目是LeetCode第189场周赛的第三题,链接:1452. 收藏清单。具体描述为:给你一个数组favoriteCompanies
,其中favoriteCompanies[i]
是第i
名用户收藏的公司清单(下标从0
开始)。请找出不是其他任何人收藏的公司清单的子集的收藏清单,并返回该清单下标。下标需要按升序排列。
1 <= favoriteCompanies.length <= 100
1 <= favoriteCompanies[i].length <= 500
1 <= favoriteCompanies[i][j].length <= 20
favoriteCompanies[i]
中的所有字符串 各不相同 。- 用户收藏的公司清单也 各不相同 ,也就是说,即便我们按字母顺序排序每个清单,
favoriteCompanies[i] != favoriteCompanies[j]
仍然成立。 - 所有字符串仅包含小写英文字母。
示例1:
输入:favoriteCompanies = [["leetcode","google","facebook"],["google","microsoft"],["google","facebook"],["google"],["amazon"]]
输出:[0,1,4]
解释:
favoriteCompanies[2]=["google","facebook"] 是 favoriteCompanies[0]=["leetcode","google","facebook"] 的子集。
favoriteCompanies[3]=["google"] 是 favoriteCompanies[0]=["leetcode","google","facebook"] 和 favoriteCompanies[1]=["google","microsoft"] 的子集。
其余的收藏清单均不是其他任何人收藏的公司清单的子集,因此,答案为 [0,1,4] 。
示例2:
输入:favoriteCompanies = [["leetcode","google","facebook"],["leetcode","amazon"],["facebook","google"]]
输出:[0,1]
解释:favoriteCompanies[2]=["facebook","google"] 是 favoriteCompanies[0]=["leetcode","google","facebook"] 的子集,因此,答案为 [0,1] 。
示例3:
输入:favoriteCompanies = [["leetcode"],["google"],["facebook"],["amazon"]]
输出:[0,1,2,3]
题目还是可以用最简单的方式来做的,因为我们需要判断某个favoriteCompanies[i]
是不是其他某个favoriteCompanies[j]
的子集,其实这就是集合操作,所以考虑把每个favoriteCompanies[i]
都先转成集合set,然后判断某个favoriteCompanies[i]
是不是其他某个favoriteCompanies[j]
的子集其实就是判断favoriteCompanies[i]
中的各个元素是否都在favoriteCompanies[j]
中。同时我们知道一个集合是另一个集合的子集的话就说明前者元素数量要比后者更少,所以可以按元素数量从多到少先排个序,然后在判断一个集合是否另一个集合的子集的时候,直接从元素数量多的往后判断,直到元素数量相等的集合就可以停止比较了。时间复杂度为
O
(
n
2
m
)
O(n^{2}m)
O(n2m)(m为单个集合的长度),空间复杂度为
O
(
m
n
)
O(mn)
O(mn)。
JAVA版代码如下:
class Solution {
private boolean contains(List<String> s1, Set<String> s2) {
for (String s : s1) {
if (!s2.contains(s)) {
return false;
}
}
return true;
}
public List<Integer> peopleIndexes(List<List<String>> favoriteCompanies) {
List<Set<String>> setList = new LinkedList<>();
int size = favoriteCompanies.size();
for (int i = 0; i < size; ++i) {
Set set = new HashSet(favoriteCompanies.get(i));
setList.add(set);
}
Collections.sort(setList, new Comparator<Set<String>>() {
@Override
public int compare(Set<String> s1, Set<String> s2) {
return s2.size() - s1.size();
}
});
List<Integer> result = new LinkedList<>();
for (int i = 0; i < size; ++i) {
List<String> set_i = favoriteCompanies.get(i);
int size_i = set_i.size();
boolean contain = false;
for (int j = 0; j < size && setList.get(j).size() > size_i; ++j) {
if (contains(set_i, setList.get(j))) {
contain = true;
break;
}
}
if (!contain) {
result.add(i);
}
}
return result;
}
}
提交结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/0fd1471cfb1e9dfc55f8620b919913dc.png)
Python版代码如下:
class Solution:
def peopleIndexes(self, favoriteCompanies: List[List[str]]) -> List[int]:
setList = [set(f) for f in favoriteCompanies]
setList.sort(key = lambda x : len(x), reverse=True)
N = len(favoriteCompanies)
result = []
for i in range(N):
set_i = set(favoriteCompanies[i])
len_i = len(set_i)
isSubset = False
j = 0
while j < N and len(setList[j]) > len_i:
if set_i.issubset(setList[j]):
isSubset = True
break
j += 1
if not isSubset:
result.append(i)
return result
提交结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6bea4314ea23529abb21e8129b8fd176.png)