簡體   English   中英

如何在Java中將兩個大列表合並到一個排序的列表中?

[英]How to merge two big Lists in one sorted List in Java?

我今天接受了一次采訪,他們給了我:

清單A具有:

f  
google   
gfk  
fat  
...

清單B具有:

hgt    
google  
koko  
fat  
ffta  
...

他們要求我將這兩個列表合並到一個排序的列表C中。

我所說:

我將列表B添加到列表A,然后從列表A創建了一個集合,然后從該集合創建了一個列表。 面試官告訴我,清單很大,這種方法對性能不利,他說這將是nlog(n)。

有什么更好的方法來解決這個問題?

好吧,您的方法將需要O(3N)額外的空間(串聯列表,集合和結果列表),這是其主要的低效率之處。

我將使用您選擇的任何排序算法對ListA和ListB進行排序(QuickSort是就地需要O(1)空間;我相信Java的默認排序策略是MergeSort,通常需要O(N)額外空間),然后使用類似於MergeSort的方式該算法檢查ListA的“當前”索引到ListB的當前索引,將應該排在最前面的元素插入ListC,然后遞增該列表的“當前”索引計數。 仍然是NlogN,但是您避免了從收集到收集的多輪轉換; 此策略僅使用O(N)個額外的空間(對於ListC;如果您對源列表進行MortSort排序,則將需要N / 2個空間)。

IMO進行采訪者想要的算法的下限是O (NlogN)。 盡管最好的解決方案在該增長模型中將擁有更少的額外空間並更有效率,但您根本無法在少於NlogN的時間內對兩個未排序的字符串列表進行排序。

編輯: Java不是我的強項(按行業我是SeeSharper),但是代碼可能類似於:

Collections.sort(listA);
Collections.sort(listB);

ListIterator<String> aIter = listA.listIterator();
ListIterator<String> bIter = listB.listIterator();
List<String> listC = new List<String>();

while(aIter.hasNext() || bIter.hasNext())
{
   if(!bIter.hasNext())
      listC.add(aIter.next());
   else if(!aIter.hasNext())
      listC.add(bIter.next());
   else
   {
      //kinda smells from a C# background to mix the List and its Iterator, 
      //but this avoids "backtracking" the Iterators when their value isn't selected.
      String a = listA[aIter.nextIndex()];
      String b = listB[bIter.nextIndex()];

      if(a==b) 
      {
         listC.add(aIter.next());
         listC.add(bIter.next());
      }
      else if(a.CompareTo(b) < 0)
         listC.add(aIter.next());
      else
         listC.add(bIter.next());          
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM