5414.收藏清单

image-20200517151026493

整体思路

  • 解题核心是处理一个集合是否为另一个集合的子集,且该判断过程对时间复杂度影响很大。
  • 细节注意
    • 提示要求返回清单,其下标需要按升序排列
    • 锁定目标集合,遍历其他集合是否包含 目标集合

直接使用List类的containsAll方法

代码

   /**
     * 使用 containsAll 优化代码
     * 超时
     */
    public List<Integer> peopleIndexes2(List<List<String>> favoriteCompanies) {
        List<Integer> ans = new ArrayList<>();
        int size = favoriteCompanies.size();
        boolean[] record = new boolean[size];
        for (int i = 0; i < size ; i++) {
            List<String> one = favoriteCompanies.get(i);
            boolean flag =true;
            for (int j = 0; j < size; j++) {
                List<String> two = favoriteCompanies.get(j);
                if(i!=j&&two.size()>=one.size()){
                    if(two.containsAll(one)){
                        flag=false;
                        break;
                    }
                }
            }
            if(flag) ans.add(i);
        }
        return ans;
    }


HashSet重构List集合

  • 由于上面超时,关键是由调用containsAll方法且其复杂度高所致的,所以通过重构输入集合,改为Set集合来优化判断子集操作。

代码

/**
     * 216 ms
     *
     * List转Set优化  150ms
     *
     */
    public List<Integer> peopleIndexes3(List<List<String>> favoriteCompanies) {
        List<Integer> ans=new ArrayList<>();
        List<Set<String>> list=new ArrayList<>();
//        for(List<String> fa:favoriteCompanies){
//            Set<String> set=new HashSet<>(fa);
//            list.add(set);
//        }
        for(List<String> fa:favoriteCompanies){
            Set<String> set=new HashSet<>();
            for(String str:fa){
                set.add(str);
            }
            list.add(set);
        }
        for(int i=0;i<favoriteCompanies.size();i++){
            Set<String> one=list.get(i);
            boolean flag=true;
            for(int j=0;j<favoriteCompanies.size();j++){
                Set<String> two = list.get(j);
                if(two.size()>=one.size()&&i!=j){
                    if(two.containsAll(one)){
                        flag=false;
                        break;
                    }
                }
            }
            if(flag) ans.add(i);
        }
        return ans;
    }

  • 在List转Set集合过程中,调用自带构造方法 Set<String> set=new HashSet<>(list); 效率不如 逐条转换

小结

  • HashSet的containsAll方法效率比ArrayList的contains方法高

  • 目前最佳耗时150ms左右 ,应该还有更优解吧

参考链接:

https://leetcode-cn.com/problems/people-whose-list-of-favorite-companies-is-not-a-subset-of-another-list/solution/javashi-xian-by-youaremydesination_/

用hashset来重构数组

原文地址:https://www.cnblogs.com/yh-simon/p/12905662.html