[英]C# Improved algorithm
我在面試(C#3.0)中被要求提供一個邏輯來從列表中刪除項目列表。
我回答了
int[] items={1,2,3,4};
List<int> newList = new List<int>() { 1, 2, 3, 4, 5, 56, 788, 9 };
newList.RemoveAll((int i) => { return items.Contains(i); });
1)面試官回答說,我采用的算法會逐漸花費時間,如果項目增長,並要求我提供更好,更快的算法。什么是有效的算法?
2)如何使用LINQ實現相同的目標?
3)他讓我提供雙向關閉的例子? (一般我知道關閉,什么是雙向關閉?,我回答說沒有這樣的術語存在,但他不滿足)。
你的答案是O(N ^ 2),因為你必須在小列表中搜索大列表中的每個元素。 你可能有運氣使用哈希表或帶二進制搜索的排序列表(在整數/字符串的情況下),以及其他各種方法來減少查找開銷,這至少會讓你到O(N日志) N)。
值得注意的是,如果小列表的大小與大列表的大小不相似,那么您的解決方案是O(N * M); 您可能希望首先優化通常較大的列表。 如果您可以對第一個列表進行排序,那么這是一個不錯的選擇; 如果不允許修改它,請不要忘記對第二個列表進行排序/哈希。
使用Except的示例
var exclusions = new List<int>() { 1, 2, 3, 4 };
var newList = new List<int>() { 1, 2, 3, 4, 5, 56, 788, 9 };
IEnumerable<int>result = newList.Except(exclusions);
如果不使用Except
,並且如果您希望您的解決方案擴展到大型列表,那么最好的辦法是對第二個列表進行排序或從中創建一個哈希表,這樣對於第一個列表中的每個元素,您都可以輕松實現在第二個中識別它。 (這就是Except
工作原理,或多或少。)
int[] items1={1,2,3,4};
List<int> newList = new List<int>() { 1, 2, 3, 4, 5, 56, 788, 9 };
newList.RemoveAll((int i) => { return items.Contains(i); });
1)采訪者回答說,如果項目增長,我采用的算法將逐漸花費時間,並要求我提供更好更快的算法。什么是有效的算法?
您的items1
的長度為m, newlist
的長度為n。 既然你執行一個線性查找items1
在每個項目newlist
,您的解決方案是O(N * M)。 從我的角度來看,您的實現是完全可以接受的,在我們需要之前,我們可能不應該擔心優化。
然而,顯然,這對面試來說還不夠好。 好吧,對於面試官來說什么“足夠好”? 誰知道。 現在,如果你不介意在面試中冒一些風險,你可以挑戰你的面試官來提供有關問題的更多細節。 告訴他許多因素和假設會影響我們代碼的速度, 尤其是數據結構的選擇:
假設你需要索引訪問newList
,然后轉換items1
到HashSet(其具有O(1)查找)提高了您的算法來為O(n),以重建陣列所需的時間。
假設newList
是元素的“包”,意味着我們不關心集合中元素的順序,那么用newList
表示newList允許我們在O(m)時間內刪除m個項。
假設我們需要保留集合中元素的插入順序,您可以將newList
表示為LinkedList {T},同時使用Dictionary {T,LinkedListNode}作為查找表。 將項添加到集合時,將其添加到LinkedList,然后將新創建的節點添加到字典中。 LinkedList保持插入順序,而Dictionary允許我們在O(m)時間內刪除m個項目。 但是,我們犧牲了對集合的索引訪問權限。
假設newList
按排序順序保存項目(似乎不是提供示例代碼的情況,但只是幽默我),大多數平衡二進制樹將刪除O(m log n)中的m項,它們也支持O (n)排序順序遍歷。 或者,如果你心情愉快,跳過清單做同樣的工作,只有傻瓜。
3)他讓我提供雙向關閉的例子? (一般我知道關閉,什么是雙向關閉?,我回答說我聽過那個詞,但他不滿意)。
我也從來沒有聽說過,谷歌似乎沒有出現任何相關的文章(除了這個帖子,前5頁的結果都不是編程甚至計算機相關)。 面試官是個白痴。
我不相信你發布的代碼有效。 標准數組沒有包含方法。*
忽略該問題,可能他在您的回復中看到的問題是,您的示例中的items.Contains方法是針對包含要刪除的項目的列表中的每個項目執行的。 結果,在完整的項目列表中搜索該列表中的每個項目。
正如其他人提到的那樣,使用Except方法會更有效率。
編輯:沒有看到你說C#3.0。 我的錯。 items1和items之間仍然存在語法錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.