// 遞歸分解,最后轉換成求2數之和
// 一個方法從 2Sum 秒殺到 100Sum
// https://leetcode-cn.com/problems/3sum/solution/yi-ge-fang-fa-tuan-mie-by-labuladong/
var nSumTarget = function (nums, n, start, target) {
let res = []
if (n < 2 || n > nums.length) {
return res
}
if (n == 2) {
let low = start;
let high = nums.length - 1;
while (low < high) {
let sum = nums[low] + nums[high];
let left = nums[low]
let right = nums[high]
if (sum < target) {
while (low < high && nums[low] === left) {
low++
}
} else if (sum > target) {
while (low < high && nums[high] === right) {
high--
}
} else {
res.push([left, right])
while (low < high && nums[low] === left) {
low++
}
while (low < high && nums[high] === right) {
high--
}
}
}
} else {
for (let i = start; i < nums.length; i++) {
let sub = nSumTarget(nums, n - 1, i + 1, target - nums[i])
for (let arr of sub) {
arr.push(nums[i])
res.push(arr)
}
while (i < nums.length && nums[i] === nums[i + 1]) {
i++
}
}
}
return res
}
var findGroup = function (nums, n, sum) {
nums = nums.sort((a, b) => a - b)
return nSumTarget(nums, n, 0, sum)
};
// 位運算
// https://blog.csdn.net/weixin_34130269/article/details/91382220
const search = (arr, count, sum) => {
// 計算某選擇情況下有幾個 `1`,也就是選擇元素的個數
const n = num => {
let count = 0
while (num) {
num &= (num - 1)
count++
}
return count
}
let len = arr.length, bit = 1 << len, res = []
// 遍歷所有的選擇情況
for (let i = 1; i < bit; i++) {
// 滿足選擇的元素個數 === count
if (n(i) === count) {
let s = 0, temp = []
// 每一種滿足個數為 N 的選擇情況下,繼續判斷是否滿足 和為 M
for (let j = 0; j < len; j++) {
// 建立映射,找出選擇位上的元素
if ((i & 1 << j) !== 0) {
s += arr[j]
temp.push(arr[j])
// 左移,從右邊的index往左邊看
// s += arr[len -1 - j]
// temp.push(arr[len -1 - j])
}
}
// 如果這種選擇情況滿足和為 M
if (s === sum) {
res.push(temp)
}
}
}
return res
}
// 0,1背包問題 (沒有去重)
function find(arr, n, sum) {
let res = []
findGroup(arr, n, sum, [])
function findGroup(arr, n, sum, oneRes) {
if (n > arr.length) return false
if (sum == 0 && n == 0) {
res.push(oneRes)
return true;
} else if (n <= 0) {
return false;
}
if (n > 0) {
let temp = arr.slice(1, arr.length)
findGroup(temp, n - 1, sum - arr[0], [...oneRes,arr[0]])
findGroup(temp, n, sum, [...oneRes])
}
}
return res
}
// 如果只要判斷能不能找到
function findGroup(arr, n, sum) {
if (n > arr.length) return false
if (sum == 0 && n == 0) {
return true;
} else if (n <= 0) {
return false;
}
if (n > 0) {
// if (arr.length === 0) return false
let temp = arr.slice(1, arr.length)
return findGroup(temp, n - 1, sum - arr[0]) || findGroup(temp, n, sum)
}
}
參考資料:
https://wizardforcel.gitbooks.io/the-art-of-programming-by-july/content/02.03.html