在我顆粒的情況下,我需要一個JavaScript代碼,發現是什麼數組a的字符串數組B.有效的方法來找到是什麼數組A的元素數組b
但要問的一般問題它更有趣:
給定陣列A
與N
長度和陣列B
,返回一個Boolean[]
陣列長度的N
使得Boolean[i]
將是true
IFF A[i]
產品在B
。
這個問題最有效的解決方案是什麼?這兩個數組都是未排序的,數組B
可以是空的,它可以大於或小於數組A
。
在我顆粒的情況下,我需要一個JavaScript代碼,發現是什麼數組a的字符串數組B.有效的方法來找到是什麼數組A的元素數組b
但要問的一般問題它更有趣:
給定陣列A
與N
長度和陣列B
,返回一個Boolean[]
陣列長度的N
使得Boolean[i]
將是true
IFF A[i]
產品在B
。
這個問題最有效的解決方案是什麼?這兩個數組都是未排序的,數組B
可以是空的,它可以大於或小於數組A
。
有幾種不同的方法可以通過改變複雜性來做到這一點。
首先,您可以對這兩個列表執行嵌套循環,並在B
中找到相應的解決方案時,打印出A
中的元素。這是O(ab)
時間和O(1)
空間。其次,您可以對兩個列表進行排序,然後逐步瀏覽列表中的鎖步,查找匹配(想象mergesort中的合併操作)。這是O(aloga + blogb)
時間和O(1)
或O(a+b)
空間,具體取決於您是否要在原地進行排序。第三,您可以對第二個列表進行排序,然後在A中一次一個二進制搜索元素。這是O(blogb + alogb)
時間和O(1)
或O(b)
空間,同樣取決於您是否在原地進行排序。
Tosters提出了一種解決方案,您可以創建一個哈希集並對其進行重複查詢。根據哈希集解決衝突的方式,這在最壞的情況下漸近地等於第一個或第三個解(底層桶可以是列表或二叉搜索樹)。
將數組B轉換爲散列集合(或其他快速搜索的集合),然後在數組A的每個元素上循環並檢查該元素是否存在於集合中。
這是非常容易的JS這樣做,我不會把它的算法:)
A.map(x => B.includes(x));
[The Tosters](https://stackoverflow.com/a/45307701/1129332)解決了它O(n)你的解是O(N^2) –
@Ilya_Gazman實際上,Toster解的最壞情況漸近界是O(n^2)或O(n log n),這取決於底層散列設置管理碰撞。 – Patrick87
的Tosters的答案是完美的隨機輸入。然而,既然你問了通用算法,我想到了下面的方法。
您需要搜索其他元素中的一個元素,因此需要對其中的一個元素進行排序以獲得最佳解決方案。讓我們考慮這兩種情況。爲了簡單起見,我們用相同的字母表示它們的大小在描述步驟之後,我在括號內提到了時間複雜度。
排序B:
1. Sort B O(B log B).
2. Iterate over each element of A and check if element exists in B, O(A log B)
Time complexity: O(A log B) + O(B log B) = O((A+B) log B)
分選:
1. Sort array A also maintaining original position in sorted array, O(A log A).
2. Iterate on each element of B and find all A's containing B. Now iterate over each searched element to get original index and update Boolean array. Also keep a marker in sorted A that the element has been searched to avoid searching if same number appears again. O(B log A)
Time complexity: O(A log A) + O(B log A) = O((A+B) log A)
其結果,溶液由日誌陣列的尺寸的因素而不同。因此,爲了獲得最佳解決方案,請使用相應的算法對較小的數組進行排序。
Tosters的答案仍然會更好,因爲它會是:O(A + B),搜索哈希是O(1)與二進制搜索log(N) –
@Ilya_Gazman查看我的其他評論;取決於散列集的實現,它可能在最壞的情況下是等價的,但它不會比'O(n log n)'更好。我喜歡這個答案,因爲它明確表示,通過對較短的答案進行排序,您可以儘可能地做到這一點 - 隱含但未在我幾乎相同的答案中陳述。 – Patrick87
@Ilya_Gazman正如帕特里克所說的那樣,我也是,在最壞的情況下,託斯特答案將是O(n^2)。其最優只適用於隨機輸入。 –
一般來說,你應該做「十字路口」 – ACV
你看過這個嗎? https://stackoverflow.com/questions/497338/efficient-list-intersection-algorithm?answertab=votes#tab-top – Dolev