查找列表是否包含另一个列表的每个元素的最佳优化方法是什么?

时间:2016-09-19 13:58:48

标签: java list time-complexity

我有两个清单:

List<String> firstList = new LinkedList<String>();
List<String> secondList = new LinkedList<String>();

我想知道列表的每个元素是否都包含在另一个列表中。 可能的解决方案可能是:

public boolean function(List<String> first, List<String> second)
{
first = firstList;
second = secondList
for (String item : firstList)
    {
            for (String elem : secondList)
            {
                if(elem.compareTo(item)!=0)
                return false;
            }
    }
 return true;
 }

我们可以看到,时间是二次的。有没有办法做得更好?

6 个答案:

答案 0 :(得分:3)

你有一个O(n * m)实现,有O(1)空间要求;您可以通过将第一个列表的元素添加到HashSet<String>,然后验证第二个列表的所有元素是否存在来实现具有O(m)空间要求的O(n + m)实现:

Set<String> firstSet = new HashSet<String>(firstList);
for (String elem : secondList) {
    if(!firstSet.contains(item)) {
        return false;
    }
}
return true;

甚至更好

return new HashSet<>(firstList).containsAll(secondList);

(谢谢,bradimus!)

注意:您的方法使用次优比较机制:您可以调用compareTo而不是调用equals,因为您无需检查单词是否为false按字母顺序排列之前或之后。

另一个问题是,当您的方法返回true时,您的方法通常会返回false,因为您过早地返回<?php public function getNextScenes($sceneId, &$nextDialogsArray) { global $array; foreach($array[$sceneId] as $dialogId => $nextSceneId) { $nextDialogsArray[$dialogId] = []; if (!empty($nextSceneId)) { $this->getNextScenes($nextSceneId, $nextDialogsArray[$dialogId]); } } } global $array; $array = [/**/]; // The input array you mentionned up there $finalArray = []; $this->getNextScenes(61, $finalArray); ?>

答案 1 :(得分:1)

public boolean function(List<String> first, List<String> second) {
    return (second.size() == first.size() && first.containsAll(second))
}

答案 2 :(得分:0)

根据一个或两个列表是否经常更改,您可能会发现将HashSet<String>用于很少更改的列表会更有效。

有关详细信息,请参阅Set operations: union, intersection, difference, symmetric difference, is subset, is superset

答案 3 :(得分:0)

试试这个:

containsAll

或者您可以使用with n as ( select row_number() over (order by (select null)) - 1 as n from master..spt_values ) select dte from (select dateadd(day, n.n, @startdate) as dte, row_number() over (order by n.n) as seqnum from n where datename(weekday, dateadd(day, n.n, @startdate) ) = @preferredCourseStartDay ) x where seqnum <= @maxCourses order by dte;

希望它有所帮助!

答案 4 :(得分:0)

我认为an existing answer可以解决您的问题。

这个想法基本上是使用两个Set并计算它们交叉的大小。

我相信如果您能够使用Set代替List,那么您可以节省contains的时间。无论发生什么,你都会有o(n)的复杂性。

修改

如果您关心在输入列表中匹配重复项,则上述解决方案可能效率不高。你可能要小心。

答案 5 :(得分:0)

 return first.containsAll(second);