JavaScript陣列最小乘積子集程式


JavaScript陣列最小乘積子集程式是一個在計算機科學和程式設計領域中常見的難題。該問題要求我們找到從給定陣列的任何子集中可以獲得的最小乘積。

陣列的最小乘積子集是指陣列元素的一個子集,該子集產生最小的乘積。有幾種演算法可用於識別此子集,包括動態規劃、貪婪演算法和分支定界法。演算法的選擇取決於手頭問題的特定約束和規範。

在本教程中,我們將討論使用JavaScript程式語言解決此問題的各種方法。我們將介紹基本的演算法方法及其使用JavaScript程式碼片段的實現。在本教程結束時,讀者將清楚地瞭解問題陳述以及使用JavaScript解決問題的各種方法。

問題陳述

給定一個整數陣列,我們需要找到陣列的最小乘積子集。陣列的乘積子集定義為陣列任何子集的乘積。

例如:

讓我們考慮陣列[2, 3, -1, 4, -2]。

此陣列的乘積子集為:

[2], [3], [-1], [4], [-2], [2, 3], [2, -1], [2, 4], [2, -2], [3, -1], [3, 4], [3, -2], [-1, 4], [-1, -2], [4, -2], [2, 3, -1], [2, 3, 4], [2, 3, -2], [2, -1, 4], [2, -1, -2], [2, 4, -2], [3, -1, 4], [3, -1, -2], [3, 4, -2], [-1, 4, -2], and [2, 3, -1, 4, -2]. 

此陣列的最小乘積子集為[-2]。

現在讓我們討論解決此問題陳述的各種演算法方法,並選擇最合適的演算法。

演算法

演算法的選擇取決於問題的具體限制和前提條件。

貪婪演算法 - 貪婪演算法是經常用於查詢陣列最小乘積子集的方法。其基本思想是從初始陣列元素開始,僅當它會產生較小的乘積時才將下一個元素附加到子集中。儘管易於實現且簡單,但貪婪演算法不一定能提供最佳解決方案,並且對於大型陣列,其效能可能會非常緩慢。

動態規劃 - 動態規劃是另一種用於解決此問題的演算法。它將問題分解成更小的子問題,並只解決每個子問題一次,利用較小子問題的解決方案來確定較大子問題的解決方案。這種方法可以節省大量時間和空間。雖然動態規劃保證最佳解,但其實現可能比貪婪演算法更復雜。

分支定界演算法 - 查詢陣列最小乘積子集的另一種方法是分支定界演算法。它包括透過分支探索多種可能性,並將搜尋限制為僅考慮有效解決方案。該演算法保證最佳解,並且在某些情況下可能比其他演算法更快。但是,它的實現可能更復雜,並且可能比其他演算法需要更多的時間和空間資源。

總之,一種簡單的辦法是生成所有子集,計算每個子集的乘積,然後返回最小乘積。

更好的解決方案需要考慮以下事實。

  • 步驟1 - 如果沒有零,並且有偶數個負數,則所有元素(除了最大的負數)的乘積將產生結果。

  • 步驟2 - 如果沒有零,並且有奇數個負數,則所有元素的乘積將產生結果。

  • 步驟3 - 如果存在零並且只有正數,則結果為0。但是,在沒有負數並且所有其他元素都為正數的特殊情況下,答案應該是最小的正數。

現在讓我們嘗試透過一個例子來理解上述方法,在這個例子中,我們將使用JavaScript實現問題陳述。

示例

此程式首先計算負數、零、最大值負數、最小值正數和非零數乘積的數量。然後,它根據負數和零的數量應用規則,以返回陣列的最小乘積子集。程式的時間複雜度為O(n),輔助空間為O(1)。

輸入1:a[] = { -1, -1, -2, 4, 3 }; n = 5

預期輸出:最小子集為[-2, 4, 3],最小乘積為-24。

輸入2:a[] = { -1, 0 }; n = 2

預期輸出:最小子集為[-1],最小乘積為-1。

function minProductSubset(a, n) {
   if (n === 1) {
      return [a[0], a[0]];
   }
   let negmax = Number.NEGATIVE_INFINITY;
   let posmin = Number.POSITIVE_INFINITY;
   let count_neg = 0, count_zero = 0;
   let subsets = [[]];  
   for (let i = 0; i < n; i++) {
      if (a[i] === 0) {
         count_zero++;
         continue;
      }
      if (a[i] < 0) {
         count_neg++;
         negmax = Math.max(negmax, a[i]);
      }
      if (a[i] > 0 && a[i] < posmin) {
         posmin = a[i];
      }
      const subsetsLength = subsets.length;
      for(let j = 0; j < subsetsLength; j++){
         const subset = [...subsets[j], a[i]];
         subsets.push(subset);
      }
   }
   if (count_zero === n || (count_neg === 0 && count_zero > 0)) {
      return [0, 0];
   }
   if (count_neg === 0) {
      return [posmin, posmin];
   }
   const negativeSubsets = subsets.filter(subset => subset.reduce((acc, cur) => acc * cur, 1) < 0);
   let minSubset = negativeSubsets[0];
   let minProduct = minSubset.reduce((acc, cur) => acc * cur, 1);
   for (let i = 1; i < negativeSubsets.length; i++) {
      const product = negativeSubsets[i].reduce((acc, cur) => acc * cur, 1);
      if (product < minProduct) {
         minSubset = negativeSubsets[i];
         minProduct = product;
      }
   }  
   return [minSubset, minProduct];
}
let a = [-1, -1, -2, 4, 3];
let n = 5;
const [minSubset, minProduct] = minProductSubset(a, n);
console.log(`The minimum subset is [ ${minSubset.join(', ')} ] and the minimum product is ${minProduct}.`);

結論

因此,在本教程中,我們學習了透過遵循簡單的演算法使用JavaScript查詢陣列的最小乘積子集。該解決方案涉及各種標準,例如陣列中存在的負數、正數和零的數量。它使用簡單的if-else條件來檢查這些標準,並相應地返回最小乘積子集。程式的時間複雜度為O(n),所需的輔助空間為O(1)。

更新於:2023年5月2日

瀏覽量:184

開啟您的職業生涯

透過完成課程獲得認證

開始學習
廣告