给你一个数组 favoriteCompanies
,其中 favoriteCompanies[i]
是第 i
名用户收藏的公司清单(下标从 0 开始)。
请找出不是其他任何人收藏的公司清单的子集的收藏清单,并返回该清单下标。下标需要按升序排列。
示例 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]
提示:
1 <= favoriteCompanies.length <= 100
1 <= favoriteCompanies[i].length <= 500
1 <= favoriteCompanies[i][j].length <= 20
favoriteCompanies[i]
中的所有字符串 各不相同 。- 用户收藏的公司清单也 各不相同 ,也就是说,即便我们按字母顺序排序每个清单,
favoriteCompanies[i] != favoriteCompanies[j]
仍然成立。 - 所有字符串仅包含小写英文字母。
方法一:哈希表
将每个 company
字符串列表都转换为一个整数类型的集合。然后遍历每个集合,判断其是否是其他集合的子集,如果不是,则将其下标加入结果集。
时间复杂度 favoriteCompanies
的长度,$m$ 为 favoriteCompanies[i]
的最大长度。
class Solution:
def peopleIndexes(self, favoriteCompanies: List[List[str]]) -> List[int]:
d = {}
idx = 0
t = []
for v in favoriteCompanies:
for c in v:
if c not in d:
d[c] = idx
idx += 1
t.append({d[c] for c in v})
ans = []
for i, nums1 in enumerate(t):
ok = True
for j, nums2 in enumerate(t):
if i == j:
continue
if not (nums1 - nums2):
ok = False
break
if ok:
ans.append(i)
return ans
class Solution {
public List<Integer> peopleIndexes(List<List<String>> favoriteCompanies) {
Map<String, Integer> d = new HashMap<>();
int idx = 0;
int n = favoriteCompanies.size();
Set<Integer>[] t = new Set[n];
for (int i = 0; i < n; ++i) {
var v = favoriteCompanies.get(i);
for (var c : v) {
if (!d.containsKey(c)) {
d.put(c, idx++);
}
}
Set<Integer> s = new HashSet<>();
for (var c : v) {
s.add(d.get(c));
}
t[i] = s;
}
List<Integer> ans = new ArrayList<>();
for (int i = 0; i < n; ++i) {
boolean ok = true;
for (int j = 0; j < n; ++j) {
if (i != j) {
if (t[j].containsAll(t[i])) {
ok = false;
break;
}
}
}
if (ok) {
ans.add(i);
}
}
return ans;
}
}
class Solution {
public:
vector<int> peopleIndexes(vector<vector<string>>& favoriteCompanies) {
unordered_map<string, int> d;
int idx = 0, n = favoriteCompanies.size();
vector<unordered_set<int>> t(n);
for (int i = 0; i < n; ++i) {
auto v = favoriteCompanies[i];
for (auto& c : v) {
if (!d.count(c)) {
d[c] = idx++;
}
}
unordered_set<int> s;
for (auto& c : v) {
s.insert(d[c]);
}
t[i] = s;
}
vector<int> ans;
for (int i = 0; i < n; ++i) {
bool ok = true;
for (int j = 0; j < n; ++j) {
if (i == j) continue;
if (check(t[i], t[j])) {
ok = false;
break;
}
}
if (ok) {
ans.push_back(i);
}
}
return ans;
}
bool check(unordered_set<int>& nums1, unordered_set<int>& nums2) {
for (int v : nums1) {
if (!nums2.count(v)) {
return false;
}
}
return true;
}
};
func peopleIndexes(favoriteCompanies [][]string) []int {
d := map[string]int{}
idx, n := 0, len(favoriteCompanies)
t := make([]map[int]bool, n)
for i, v := range favoriteCompanies {
for _, c := range v {
if _, ok := d[c]; !ok {
d[c] = idx
idx++
}
}
s := map[int]bool{}
for _, c := range v {
s[d[c]] = true
}
t[i] = s
}
ans := []int{}
check := func(nums1, nums2 map[int]bool) bool {
for v, _ := range nums1 {
if _, ok := nums2[v]; !ok {
return false
}
}
return true
}
for i := 0; i < n; i++ {
ok := true
for j := 0; j < n; j++ {
if i == j {
continue
}
if check(t[i], t[j]) {
ok = false
break
}
}
if ok {
ans = append(ans, i)
}
}
return ans
}