1. 程式人生 > >JavaScript刷LeetCode -- 923. 3Sum With Multiplicity

JavaScript刷LeetCode -- 923. 3Sum With Multiplicity

一、題目

Given an integer array A, and an integer target, return the number of tuples i, j, k such that i < j < k and A[i] + A[j] + A[k] == target.

As the answer can be very large, return it modulo 10^9 + 7.

二、題目大意

從陣列A中找出三個數的組合,使得相加的結果為target,要求給出所有這種組合的個數。(答案可能很大,記得取模運算)

  Note:
  3 <= A.length <= 3000
  0 <= A[i] <= 100
  0 <= target <= 300

三、解題思路

最容易想到的就是找出陣列中的所有組合,然後和值是否滿足target:

const threeSumMulti = (A, target) => {
  const max = A.length
  if (max < 3) {
    return 0
  }

  let result = 0

  for (let a = 0; a < max - 2; a++) {
    for (let b = a + 1; b < max - 1; b++) {
      for (let c = b + 1; c < max; c++) {
        if (A[a] + A[b] + A[c] === target) {
          result++
        }
      }
    }
  }

  return result
}

同題目中的限制條件可以看出陣列A的範圍還是很大的,所以這種暴力求解的方法會超時。

另一種思路則是從target出發,通過三重迴圈(target的範圍並不是特別的大)找出能夠構成三數之和為target的組合,再判斷這些數是否能從陣列中取出。

在實現的過程中需要注意幾點:

  • 通過target - a -b可以計算出第三個數,從而減少一層迴圈。
  • 遍歷陣列A記錄其中元素的個數,用來判斷3數是否合法以及計算後面的組合個數。
  • 涉及到數學中的組合知識。

四、程式碼實現

const threeSumMulti = (A, target) => {
  const max = A.length

  const MAX = 10 ** 9 + 7
  const hash = {}
  // 統計數字出現的次數
  for (let i = 0; i < max; i++) {
    const item = A[i]
    if (hash[item] == null) {
      hash[item] = 0
    }
    hash[item]++
  }
  let result = 0

  // 嘗試尋找這三個數
  for (let a = 0; a <= target; a++) {
    for (let b = a; b <= target; b++) {
      const c = target - a - b
      // 不合法的情況
      if (!hash[a] || !hash[b] || !hash[c] || c < 0) {
        continue
      }

      // 小心重複的組合
      if (c < b) {
        continue
      }
      /**
       * a <= b <= c
       * 有一個數相等
       * 有兩個數相等
       * 
       */
      if (a === b && b === c) {
        result += ((hash[a] * (hash[a] - 1) * (hash[a] - 2)) / 6) % MAX
      } else if (a === b && a !== c) {
        result += (hash[a] * (hash[a] - 1) / 2 * hash[c]) % MAX
      } else if (a !== b && b === c) {
        result += (hash[b] * (hash[b] - 1 ) / 2 * hash[a]) % MAX
      } else {
        result += (hash[a] * hash[b] * hash[c]) % MAX
      }
    }
  }

  return result
}

如果本文對您有幫助,歡迎關注我的微信公眾號【超愛敲程式碼】,為您推送更多內容,ε=ε=ε=┏(゜ロ゜;)┛。