Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.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_Collections - Fatal编程技术网

Java 数组列表算法-访问

Java 数组列表算法-访问,java,algorithm,collections,Java,Algorithm,Collections,在今天的一次采访中,我被问到了这个问题。我尝试了一个解决方案,但想知道是否有更好的方法来解决这个问题: 问题:我有一个包含500000个元素的arraylist,因此arraylist中每个元素的值都与索引相同。对于ex:list.get(0)=0;列表。获取(1)=1…等。但只有一个元素与此排序不同步[即list.get(i)!=i]。你如何找到那个元素 我的答案:使用多个线程在列表上迭代,每次比较列表时,每个线程都处理arraylist的某个拼接。使用i获取(i)。找到该元素后,设置一些布尔

在今天的一次采访中,我被问到了这个问题。我尝试了一个解决方案,但想知道是否有更好的方法来解决这个问题:

问题:我有一个包含500000个元素的arraylist,因此arraylist中每个元素的值都与索引相同。对于ex:list.get(0)=0;列表。获取(1)=1…等。但只有一个元素与此排序不同步[即list.get(i)!=i]。你如何找到那个元素

我的答案:使用多个线程在列表上迭代,每次比较列表时,每个线程都处理arraylist的某个拼接。使用i获取(i)。找到该元素后,设置一些布尔变量,以向其他线程指示已找到该元素


有没有一种方法可以在不重复列表的情况下解决此问题?或者更好的方法?

在最坏的情况下,您必须检查每个元素,因此无法改善时间复杂性

记住这一点,最好的算法是从头到尾扫描数组列表。这样,您就可以充分利用可用的内存带宽


我并不完全清楚线程是如何或为什么进入画面的。这似乎不合适。这是问题的一部分吗?

你没有比
O(n)
更好的了

其次,我认为在这些问题中谈论线程和多线程是个坏主意。他们根本不感兴趣。最后,你有一个O(无论什么)的运行时,你的常数被删除了

也许面试官指的是一个排序数组,元素从0到n-1,索引从0到n-1。然后将一个元素移动到不同的位置。但这意味着所有剩余的元素都有不同的索引!在这种情况下,您可以使用二进制搜索改进搜索:


然后可以在
O(logn)
中获取元素。从中间开始,检查索引是否等于元素。如果相等,则对上半部分执行相同的操作,如果不使用另一部分。

关于@aix的答案,每个循环执行两次检查如何:

for (int i = 0; i < list.size / 2; i++)
{
  if (i != list.get(i))
  {
    return i;
  }
  else if (list.size - i != list.get(list.size - i)
  {
    return list.size - i;
  }
}
for(int i=0;i

我不认为线程进入竞技场…

答案是:一次迭代。你提到的原因的并发性是他们想要的

事实上,自java 8以来,无论并行与否,解决方案都很简单。我认为最重要的是:

OptionalInt foundInt = IntStream.range(0, list.size())
    .parallelStream()
    .filter(i -> i != list.get(i))
    .findAny();
arraylists=newarraylist();

对于(int i=0;尽管我同意你的观点,但这样的问题很无聊。@aix不,这是我对面试官的回答。我原以为使用数组拼接和处理数组列表的迭代实际上会更好,但后来我意识到O(n)即使使用多个线程也无法改进。事实上,线程只会带来更大的复杂性。尽管您可以在同一个循环中从列表的两端解决问题。@NickHolt:嗯,有很多种方法可以尝试部分展开该循环。这需要分析才能说明关于p的任何有意义的内容但是性能影响(当然它不会改变
O(n)
)。是的,如果内存I/O是瓶颈,添加线程也不会有帮助。大多数CPU都有一个外部内存接口,所以多个内核上的更多线程也不会有帮助。我同意。现在单线程在
O(log n)上迭代50万个线程也不算多
算法在列表上似乎失败了
1,0,2,3,4,5
。你不是说移动,而是说删除?然后它就工作了。@b我想他的意思是,如果一般规则是f(n+1)=f(n)+1(除了那个特定目标),那么二进制搜索在这里是理想的。@b问题:为什么它在这个列表上失败了?我会在O(log n)中找到元素0…在这种情况下,每个元素都有一个不同的索引..因此我们寻找索引0…@duedl0r我将元素1移动到元素0,但其他所有元素的索引都没有被触及。因此,当你查看中点时,你会看到它没有改变,并查看上半部分。我的观点是,在没有性能基准的情况下,循环展开最好让JIT编译器来处理。@aix是的,我同意,纯粹从可读性的角度来看,我会避免这样做。由于没有关于这个数字在列表中的位置的提示,这个问题有点无聊。我想你必须解释什么“只有一个元素不同步”真的意思是..没有意义..看下面我的答案。我想如果你移动一个元素,所有剩余的元素都会不同步,不是吗?@dued0或者该元素没有被删除。面试官问如何识别与索引值不同的元素。我想它不会找到同时访问不同元素的方法区域…更多的是减少数据访问。。。
OptionalInt foundInt = IntStream.range(0, list.size())
    .parallelStream()
    .filter(i -> i != list.get(i))
    .findAny();
ArrayList<Integer> s = new ArrayList<Integer>();

for (int i=0; i<500000; i++) {
    s.add(i);
}

s.set(13, 500002);

for (int j=0; j<s.size(); j++) {
    if (j != s.get(j)) {
        System.out.println(j + " " + s.get(j));
    }   
}