JavaScript刷LeetCode -- 923. 3Sum With Multiplicity
阿新 • • 發佈:2018-12-23
一、題目
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 }
如果本文對您有幫助,歡迎關注我的微信公眾號【超愛敲程式碼】,為您推送更多內容,ε=ε=ε=┏(゜ロ゜;)┛。