leetcode 5414 收藏清单

题目描述:

  给你一个数组 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] 仍然成立。所有字符串仅包含小写英文字母。

题解:

  判断集合是否为其他集合的子集,我们记$favoriteCompanies.length$为$n$、记$favoriteCompanies[i].length$为$m$、记$favoriteCompanies[i][j].length$为$k$。我们先按照集合的大小排序,用一个vector<int> ans存一下独立集合(不是任何集合的子集)的index。接着从集合size()最大的那个集合开始遍历,如果其能够在ans中找到一个包含其的集合,那么pass;否则作为新的独立子集加入ans。这么做可行的原因是,ans包含了比当前遍历到的集合size()大的所有集合(对于没有加入$ans$的集合$t$,一定有一个集合$z \in ans$,$t$是$z$的子集)。是否为子集的判断用STL的inclueds函数就可以了,按照集合的size()排序用map就可以了,代码如下:

class Solution {
public:
        vector<int> peopleIndexes(vector<vector<string>>& favoriteCompanies) {
        for (auto& f : favoriteCompanies) {
            sort(f.begin(), f.end());
        }

        map<int, vector<int>> mapSizeIndex;
        for (int i = 0; i < favoriteCompanies.size(); i++) {
            mapSizeIndex[favoriteCompanies[i].size()].push_back(i);
        }

        vector<int> ans;
        for (auto it = mapSizeIndex.rbegin(); it != mapSizeIndex.rend(); it++) {
            for (auto& p : it->second) {
                if (it != mapSizeIndex.rbegin() && checkIncludes(favoriteCompanies, ans, p)) continue;
                ans.push_back(p);
            }
        }

        sort(ans.begin(), ans.end());
        return ans;
    }

    bool checkIncludes(vector<vector<string>>& fc, vector<int>& ans, int p) {
        for (auto i : ans) {
            if (includes(fc[i].begin(), fc[i].end(), fc[p].begin(), fc[p].end())) return true;
        }
        return false;
    } 
};

 

posted @ 2020-05-18 09:47  猪突猛进!!!  阅读(175)  评论(0编辑  收藏  举报