题:
思:
不断的考虑新的一个List,来更新map,map用于保存当前所有的满足条件的收藏清单
如果新的list和过去的某一个list长度一样,那么他们一定不同
如果新的list包含过去的某一个list的全部,那么就删除原来的,添加新的。可能会同时删除很多个
如果新的list被包含于过去的一个list,那么新的list将不再考虑,直接考虑下一个list
码:
public List<Integer> peopleIndexes(List<List<String>> favoriteCompanies) {
// map用于保存当前所有的满足条件的收藏清单
Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();
map.put(0, favoriteCompanies.get(0));
for (int i = 1; i < favoriteCompanies.size(); i++) {
List<String> curList = favoriteCompanies.get(i);
List<Integer> daiShanChuLists = new ArrayList<>();
boolean keJiaRu = true;
for (int j = 0; j < i; j++) {
List<String> preList = map.get(j);
if(preList == null) continue;
// 如果新的list和过去的某一个list长度一样,那么他们一定不同
// 如果新的list包含过去的某一个list的全部,那么就删除原来的,添加新的。可能会同时删除很多个
// 如果新的list被包含于过去的一个list,那么新的list将不再考虑,直接考虑下一个list
if (preList.size() == curList.size())
continue;
else if (curList.size() > preList.size()) {
// 判断当前的preList是否将要被删除
int k;
for (k = 0; k < preList.size(); k++) {
if (!curList.contains(preList.get(k)))
break;
}
if (k == preList.size()) {
// 将要删除它
daiShanChuLists.add(j);
}
} else {
// 判断当前的preList是否能包含curList,如果能,则直接跳过当前curList
// 如果不能,则把它加入
int k;
for (k = 0; k < curList.size(); k++) {
if (!preList.contains(curList.get(k)))
break;
}
if (k == curList.size()) {
keJiaRu = false;
break;
}
}
}
if (daiShanChuLists.size() != 0) {
for(int p = 0 ; p < daiShanChuLists.size() ; p++){
map.remove(daiShanChuLists.get(p));
}
map.put(i,curList);
}else if(keJiaRu){
map.put(i,curList);
}
}
Set<Integer> integers = map.keySet();
List<Integer> ans = new ArrayList<>(integers);
ans.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});
return ans;
}
结果: 54/55 超出时间限制
收获:
int k;
for (k = 0; k < preList.size(); k++) {
if (!curList.contains(preList.get(k)))
break;
}
if (k == preList.size()) {
// 将要删除它
daiShanChuLists.add(j);
}
这段代码可以用这个api来完成
if(curList.containsAll(preList)){
daiShanChuLists.add(j);
}
如何解决超时呢?
现在我们用的是List的containsAll方法,它的时间复杂度是O(mn)
但是如果我们换成Set的containsAll方法,它的时间复杂度就是O(n)
因为list的contains开销是O(m),所以containsAll开销是O(mn);
set的contains开销是O(1),所以containsAll开销是O(n)。