JavaScript 中查詢任意數量陣列的公共元素


問題陳述要求您為任意數量的陣列找到解決方案,以便使用者需要找到每個任意陣列中存在的公共元素。這裡將任意陣列稱為陣列物件。不應將查詢兩個陣列之間的公共元素與之混淆,這不是問題陳述所要求的。它定義並探索了各種可以幫助我們找到 JavaScript 中給定源資料中存在的互斥最小公因數的演算法。

什麼是 JavaScript 中的任意數量陣列

任意數量是指不遵循任何特定模式的不確定的大量值,您只需隨機為它們提供值。類似地,任意數量的陣列是指給定隨機元素的兩個以上陣列集,其中如此數量的不同陣列被打包在一個稱為陣列物件的 物件中。問題陳述說要查詢此類隨機、不同且超過兩個可數陣列集中存在的交集元素。

不同的陣列集可以打包在陣列的陣列或陣列的物件中,因為問題陳述中沒有提到此類條件。

此處的演算法討論瞭解決陣列本身中存在的任意數量陣列的問題陳述。

步驟 1:宣告一個名為 findCommonElements 的函式,該函式以陣列輸入作為源。

步驟 2:宣告並初始化結果陣列為空陣列。

步驟 3:使用外部 for 迴圈遍歷所有任意陣列的第一個陣列,其中 i 索引將跟蹤第一個陣列及其元素從 arr.length-1 的反向方向開始,因為在存在大量陣列或陣列中有多個數組的情況下,每次迭代迴圈時計算 length 屬性效率不高,這並不夠簡單。

步驟 4:巢狀的第二個迴圈將遍歷剩餘的陣列集或大型陣列中存在的剩餘任意陣列,並使用 j 索引。

步驟 5:indexOf 方法用於查詢第一個陣列中存在的元素的值到剩餘的任意集中。

步驟 6:如果在剩餘陣列中找不到第一個陣列的特定值,我們只需使用 break 語句跳到下一次迭代並嘗試查詢其他任意陣列中存在的公共元素。

步驟 7:所有迴圈結束後,我們使用 j 索引來判斷其值是否已到達第一個陣列本身,這是比較的主要來源,只需將比較過程中從 arr[0][i] 獲得的任何值推送到結果陣列中,因為陣列不能與自身進行比較。

主程式碼 - 使用迴圈

示例

function findCommonElements(arr) {
  let commonArray = [];
  for (let i = arr[0].length - 1; i >= 0; i--) {
   let isCommon = true;
   for (let j = arr.length - 1; j > 0; j--) {
    if (arr[j].indexOf(arr[0][i]) === -1) {
     isCommon = false;
     break;
    }
   }
   if (isCommon) {
    commonArray.push(arr[0][i]);
   }
  }
  return commonArray;
}

const arrayOfArrays = [
  [1, 4, 6, 78, 8, 9, 124, 44],
  [44, 6, 9],
  [124, 44, 16, 9]
];

console.log(findCommonElements(arrayOfArrays));

輸出

[ 44, 9 ]

時間和空間複雜度

在上述演算法中,我們使用了巢狀迴圈,該迴圈一直持續到陣列的長度,因此在最壞情況下導致 O(n^2) 的時間複雜度。空間複雜度為 O(1)

上述演算法可以透過遵循 JavaScript 中的對映和集合進行最佳化

演算法 - 使用 Map 和 Set

該演算法在時間複雜度方面現在效率更高,但肯定犧牲了空間複雜度,

步驟 1:宣告一個名為 commonElementFind 的函式,該函式以 mainArray 作為輸入源。

步驟 2:宣告並初始化一個帶有空值的對映。

步驟 3:我們將遍歷陣列的每個子陣列,以在 JavaScript 中建立並轉換每個子陣列為 Set,以去除重複項並使演算法在查詢任意數量陣列中存在的公共元素方面更高效、更快捷

步驟 4:一旦每個子陣列轉換為每個唯一的集合,我們現在將透過計算它們在整個公共和單個對映中的出現次數來設定它們的對映值

步驟 5:如果集合的值已存在於對映中,則將其遞增 1,否則將其初始化並賦值為 1

步驟 6:一旦所有迴圈和每個 Set 元素的遍歷完成,我們將對映物件的鍵以檢查對映的任何鍵的長度是否等於陣列的長度,這肯定會表明公共元素的行為

步驟 7:一旦我們找到等於陣列長度的鍵,這意味著該特定元素已出現在陣列的所有子陣列中,因此我們在 JavaScript 中找到任意數量陣列中存在的公共元素或值。

主程式碼 - 使用 Map 和 Set

示例

function commonElementFind(mainArray)
{   

   const newMap = {};

   for(let subArray of mainArray)
   {  

     const newSet = new Set(subArray);

         newSet.forEach(val => {

       if(newMap[val])
       { 
         newMap[val] = newMap[val] + 1;
       }
       else 
       {
         newMap[val] = 1;
       }
   })

   }
Object.keys(newMap).map((key)=> {

     if(newMap[key] === arr.length) {

       console.log(key);

     }
   });
}

const arr = [
   [15, 23, 36, 49, 104, 211],
   [9, 12, 23],
   [11, 17, 18, 23, 38],
   [13, 21, 23, 27, 40, 85]
  ];
  
  commonElementFind(arr);

輸出

23

時間和空間複雜度

由於我們使用 JavaScript 的強大概念 Map 和 Set 優化了演算法,因此它將演算法的時間複雜度從 O(n^2) 降至 O(n),但由於 Map 和 Set 用於額外的記憶體分配,我們也犧牲了空間複雜度以達到線性時間,即 O(n)。

結論

這就是我們如何在編碼的上下文中以邏輯和有效的方式解決上述問題陳述的方式,將程式碼從巢狀迴圈更改為 Map 和 Set 功能,這使我們擁有巨大的能力來遍歷和使用它執行操作,從而實現線性時間和空間複雜度。

更新於:2023 年 8 月 22 日

214 次檢視

啟動你的 職業生涯

透過完成課程獲得認證

開始
廣告
© . All rights reserved.