Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何降低双表搜索算法的复杂度?_Java_Algorithm - Fatal编程技术网

Java 如何降低双表搜索算法的复杂度?

Java 如何降低双表搜索算法的复杂度?,java,algorithm,Java,Algorithm,我必须在两个列表中找到一些常用项。我不能排序,顺序很重要。必须找出secondList中有多少元素出现在firstList中。现在它看起来如下所示: int[] firstList; int[] secondList; int iterator=0; for(int i:firstList){ while(i <= secondList[iterator]/* two conditions more */){ iterator++; //some action

我必须在两个列表中找到一些常用项。我不能排序,顺序很重要。必须找出
secondList
中有多少元素出现在
firstList
中。现在它看起来如下所示:

int[] firstList;
int[] secondList;
int iterator=0;
for(int i:firstList){
 while(i <= secondList[iterator]/* two conditions more */){
       iterator++;
       //some actions
   }
}
什么时候


通过A列表到元素j-1的下一次迭代(平均值
)(int z=0;z我的方法是-将第一个数组中的所有元素放在一个
哈希集中,然后在第二个数组上进行迭代。这将复杂性降低到两个数组长度的总和。这有占用额外内存的缺点,但除非你使用更多内存,否则我认为你无法改进你的暴力行为rce解决方案

编辑:为了避免进一步的争议。如果允许在第一个数组中有重复的元素,并且您实际上关心第二个数组中的元素与第一个数组中的元素匹配多少次,请使用
HashMultiSet

  • 将第一个列表中的所有项目放在一个集合中
  • 对于第二个列表的每个项目,测试其是否在集合中
不到n x n就解决了

编辑以请使用fge:)

您可以使用项目作为键、出现次数作为值的映射,而不是集合

然后,对于第二个列表中的每个项目,如果它存在于映射中,则在第一个列表中每次出现时执行一次操作(字典条目的值)。

import java.util.*;
int[]firstList;
int[]第二列表;
int迭代器=0;
HashSet hs=新的HashSet(Arrays.asList(firstList));
HashSet result=新的HashSet();

而(iOK,所以如果第一个或第二个数组中都没有重复项,那么这个解决方案将起作用。因为问题没有说明,我们无法确定

首先,从第一个数组构建一个
LinkedHashSet
,从第二个数组构建一个
HashSet

第二,在第一个集合中只保留第二个集合中的元素

第三,迭代第一个集合并继续:

// A LinkedHashSet retains insertion order
Set<Integer> first = LinkedHashSet<Integer>(Arrays.asList(firstArray));
// A HashSet does not but we don't care
Set<Integer> second = new HashSet<Integer>(Arrays.asList(secondArray));

// Retain in first only what is in second
first.retainAll(second);

// Iterate

for (int i: first)
    doSomething();
//LinkedHashSet保留插入顺序
Set first=LinkedHashSet(Arrays.asList(firstArray));
//HashSet没有,但我们不在乎
Set second=新的HashSet(Arrays.asList(secondArray));
//只保留第二个中的内容
第一,保留(第二);
//迭代
对于(int i:第一个)
doSomething();

仅仅因为顺序很重要并不意味着你不能对任何一个列表(或两者)进行排序。这只意味着你必须先复制,然后才能对任何内容进行排序。当然,复制需要额外的内存,排序需要额外的处理时间……但我想所有的解决方案都比O(n^2)好将需要额外的内存和处理时间(对于建议的哈希集解决方案也是如此-将所有值添加到哈希集会花费额外的内存和处理时间)

在O(n*log n)时间内可以对两个列表进行排序,在O(n)时间内可以找到列表排序后的公共元素。它是否比本地O(n^2)方法快取决于列表的大小。最后,只有测试不同的方法才能告诉您哪种方法最快(这些测试应该使用实际的列表大小,正如在最终代码中预期的那样)


Big-O表示法不是告诉你任何关于绝对速度的表示法,它只告诉你一些关于相对速度的信息。例如,如果你有两种算法从一组输入元素计算一个值,一种是O(1),另一种是O(n),这并不意味着O(1)解决方案总是更快。这是对big-O表示法的一个严重误解!这只意味着如果输入元素的数量翻倍,O(1)解决方案仍将花费大约相同的时间,而O(n)则解决方案需要的时间大约是以前的两倍。因此,毫无疑问,通过不断增加输入元素的数量,O(1)解决方案一定会比O(n)解决方案快,但对于非常小的元素集,O(1)解决方案实际上可能比O(n)慢解决方案。

列表的最大可能大小是多少?你能举个例子吗?这还不清楚:“必须找出第二个列表中有多少元素出现在第一个列表中。”如果你不打算使用O(n)存储,那么理论上你无法比O(n^2)更好地解决这个问题。您能解释一件事吗?您正在查找一个列表中有多少个元素出现在第二个列表中,为什么在这种情况下顺序很重要?@Swapnil Max size不大于2^20。不幸的是,
哈希集
将被吞没duplicates@fge你只关心一个元素是否出现在两个数组中,而不关心它出现了多少次!@fge我不同意,他说e> 这意味着他不在乎它们“多少次”common@fge若您想要的结果是两个数组中索引的函数,那个么不能在小于O(nxn)的范围内得到它@Ignits not true-使用相同的方法和
HashMap
HashMultiMap
,取决于语句的读数a
Set
吞咽重复项,OP没有说明是否可能存在重复项。这没有多大意义!如果OP想要两个列表之间的重复项,我们不关心两个列表之一中的重复项,是吗?是的,我们关心:这意味着操作可能必须执行两次,而不是一次。
B[i] >= A[j]
         return B[i],A[j-1]
import java.util.*; 

int[] firstList;
int[] secondList;
int iterator=0;   

HashSet hs = new HashSet(Arrays.asList(firstList));
HashSet result = new HashSet();

while(i <= secondList.length){
  if (hs.contains( secondList[iterator]))  
  {
    result.add(secondList[iterator]);
  }   
 iterator++;
 }
// A LinkedHashSet retains insertion order
Set<Integer> first = LinkedHashSet<Integer>(Arrays.asList(firstArray));
// A HashSet does not but we don't care
Set<Integer> second = new HashSet<Integer>(Arrays.asList(secondArray));

// Retain in first only what is in second
first.retainAll(second);

// Iterate

for (int i: first)
    doSomething();